X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.utils.datastructures%2Fsrc%2Forg%2Fsimantics%2Futils%2Fdatastructures%2FMapList.java;h=cdfa9f7829ddbfb4065d95f9c4ef27cf774e306d;hp=aeef0fd1fff48eae3cb759b9719fe50b851eb012;hb=c4f4133d961fb96ae7a99c86678cb09fb9aff1f5;hpb=969bd23cab98a79ca9101af33334000879fb60c5 diff --git a/bundles/org.simantics.utils.datastructures/src/org/simantics/utils/datastructures/MapList.java b/bundles/org.simantics.utils.datastructures/src/org/simantics/utils/datastructures/MapList.java index aeef0fd1f..cdfa9f782 100644 --- a/bundles/org.simantics.utils.datastructures/src/org/simantics/utils/datastructures/MapList.java +++ b/bundles/org.simantics.utils.datastructures/src/org/simantics/utils/datastructures/MapList.java @@ -1,295 +1,294 @@ -/******************************************************************************* - * 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 - *******************************************************************************/ -/* - * 16.8.2006 - */ -package org.simantics.utils.datastructures; - -import gnu.trove.map.hash.THashMap; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -/** - * MapList is a data structure with map on left side and arraylist on right side. - *

- * - * @author Toni Kalajainen - */ -public class MapList { - - @SuppressWarnings("rawtypes") - public static final MapList EMPTY_MAPLIST = new MapList() { - private static final String IMMUTABLE_MSG = "Cannot modify immutable empty MapList"; - - @Override - public void add(Object key) { - throw new UnsupportedOperationException(IMMUTABLE_MSG); - } - @Override - public void add(Object key, int index, Object value) { - throw new UnsupportedOperationException(IMMUTABLE_MSG); - } - @Override - public void add(Object key, Object value) { - throw new UnsupportedOperationException(IMMUTABLE_MSG); - } - @Override - public void addAll(Object key, Collection values) { - throw new UnsupportedOperationException(IMMUTABLE_MSG); - } - @Override - public void clear() { - throw new UnsupportedOperationException(IMMUTABLE_MSG); - } - @Override - public boolean remove(Object key) { - throw new UnsupportedOperationException(IMMUTABLE_MSG); - } - public boolean remove(Object key, Object value) { - throw new UnsupportedOperationException(IMMUTABLE_MSG); - } - }; - - @SuppressWarnings("unchecked") - public static MapList emptyMapList() { - return EMPTY_MAPLIST; - } - - protected Map> lists; - - public MapList() { - lists = new THashMap>(); - } - - @SuppressWarnings("unchecked") - public MapList( Class mapClass ) { - try { - lists = (Map>) mapClass.newInstance(); - } catch (InstantiationException e) { - throw new RuntimeException( e ); - } catch (IllegalAccessException e) { - throw new RuntimeException( e ); - } - } - - public MapList(MapList copyFrom) { - for (Entry> e : copyFrom.lists.entrySet()) - lists.put( e.getKey(), new ArrayList(e.getValue()) ); - } - - public static MapList use( Map> map ) { - MapList result = new MapList(); - result.lists = map; - return result; - } - - public void add(L key) { - getOrCreateList(key); - } - - public void add(L key, R value) - { - List list = getOrCreateList(key); - list.add(value); - } - - public void add(L key, int index, R value) - { - ArrayList list = getOrCreateList(key); - list.add(index, value); - } - - public void addAll(L key, Collection values) { - ArrayList list = getOrCreateList(key); - list.addAll(values); - } - - private ArrayList getOrCreateList(L key) - { - ArrayList list = (ArrayList) lists.get(key); - if (list==null) { - list = new ArrayList(1); - lists.put(key, list); - } - return list; - } - - private List getList(L key) - { - return lists.get(key); - } - - public boolean remove(L key, R value) - { - List list = getList(key); - if (list==null) return false; - boolean result = list.remove(value); - if (list.size()==0) - lists.remove(key); - return result; - } - - public boolean remove(L key) - { - List list = getList(key); - if (list==null) return false; - lists.remove(key); - return true; - } - - public void clear() - { - lists.clear(); - } - - public L[] getKeys(L[] list) - { - return lists.keySet().toArray(list); - } - - public Set getKeys() - { - return lists.keySet(); - } - - public int getKeySize() { - return lists.size(); - } - - public boolean containsKey(L key) - { - return lists.containsKey(key); - } - - public boolean contains(L key, R obj) - { - List l = lists.get(key); - if (l==null) return false; - return l.contains(obj); - - } - - public R[] getValues(L key, R[] list) - { - List l = lists.get(key); - if (l==null) return null; - return l.toArray(list); - } - - /** - * @param key - * the key to get values for - * @param list - * the list to fill with existing values for specified key. Fills - * this array with at maximum as many values as there is room for - * in the array even if there are more values available in the - * maplist for the specified key. - * @return the amount of values existing for the key. May be smaller or - * larger than the size of the provided list. If smaller, only the - * first array indexes will be filled with data and if larger, all - * array indexes will be filled with data. - */ - public int getAtMostValues(L key, R[] list) - { - List l = lists.get(key); - if (l==null) return 0; - int valueCount = l.size(); - int size = Math.min(valueCount, list.length); - for (int i = 0; i < size; ++i) - list[i] = l.get(i); - return valueCount; - } - - /** - * Returns a the internal list values for the specified key. The list is - * valid as long as it contains elements. The list should not be modified - * but the return value of this method does not enforce it like - * {@link #getValues(Object)} does. Use this method when you know you will - * not risk a 3rd party modifying the returned list and you want to avoid - * the cost of extra memory allocation through - * {@link Collections#unmodifiableList(List)}. - * - * @param key - * the key to look values for - * @return empty unmodifiable list if there is no list with the specified - * key, otherwise an unmodifiable version of the stored list - */ - public List getValuesUnsafe(L key) - { - List l = lists.get(key); - return l != null ? l : Collections.emptyList(); - } - - /** - * Returns a read-only reference to the values. The list is valid as long as - * it contains elements. - * - * @param key - * @return empty unmodifiable list if there is no list with the specified key, - * otherwise an unmodifiable version of the stored list - */ - public List getValues(L key) - { - List l = lists.get(key); - if (l==null) return Collections.emptyList(); - return Collections.unmodifiableList(l); - } - - /** - * Returns a copy of the values - * - * @param key - * @return empty unmodifiable list if there is no list with the specified key, - * otherwise a copy of the stored list - */ - public List getValuesSnapshot(L key) - { - List l = lists.get(key); - if (l==null) return Collections.emptyList(); - return new ArrayList(l); - } - - public List getAllValuesSnapshot() - { - return getAllValuesSnapshot(null); - } - - public List getAllValuesSnapshot(List result) - { - if (result == null) - result = new ArrayList(); - for (List right : lists.values()) { - result.addAll(right); - } - return result; - } - - public boolean isEmpty() { - return lists.isEmpty(); - } - - /** - * Makes _this_ maplist immutable. - */ - public void makeImmutable() { - for (Entry> e : lists.entrySet()) - lists.put(e.getKey(), Collections.unmodifiableList(e.getValue())); - lists = Collections.unmodifiableMap(lists); - } - -} +/******************************************************************************* + * 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 + *******************************************************************************/ +/* + * 16.8.2006 + */ +package org.simantics.utils.datastructures; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +/** + * MapList is a data structure with map on left side and arraylist on right side. + *

+ * + * @author Toni Kalajainen + */ +public class MapList { + + @SuppressWarnings("rawtypes") + public static final MapList EMPTY_MAPLIST = new MapList() { + private static final String IMMUTABLE_MSG = "Cannot modify immutable empty MapList"; + + @Override + public void add(Object key) { + throw new UnsupportedOperationException(IMMUTABLE_MSG); + } + @Override + public void add(Object key, int index, Object value) { + throw new UnsupportedOperationException(IMMUTABLE_MSG); + } + @Override + public void add(Object key, Object value) { + throw new UnsupportedOperationException(IMMUTABLE_MSG); + } + @Override + public void addAll(Object key, Collection values) { + throw new UnsupportedOperationException(IMMUTABLE_MSG); + } + @Override + public void clear() { + throw new UnsupportedOperationException(IMMUTABLE_MSG); + } + @Override + public boolean remove(Object key) { + throw new UnsupportedOperationException(IMMUTABLE_MSG); + } + public boolean remove(Object key, Object value) { + throw new UnsupportedOperationException(IMMUTABLE_MSG); + } + }; + + @SuppressWarnings("unchecked") + public static MapList emptyMapList() { + return EMPTY_MAPLIST; + } + + protected Map> lists; + + public MapList() { + lists = new HashMap>(); + } + + @SuppressWarnings("unchecked") + public MapList( Class mapClass ) { + try { + lists = (Map>) mapClass.newInstance(); + } catch (InstantiationException e) { + throw new RuntimeException( e ); + } catch (IllegalAccessException e) { + throw new RuntimeException( e ); + } + } + + public MapList(MapList copyFrom) { + for (Entry> e : copyFrom.lists.entrySet()) + lists.put( e.getKey(), new ArrayList(e.getValue()) ); + } + + public static MapList use( Map> map ) { + MapList result = new MapList(); + result.lists = map; + return result; + } + + public void add(L key) { + getOrCreateList(key); + } + + public void add(L key, R value) + { + List list = getOrCreateList(key); + list.add(value); + } + + public void add(L key, int index, R value) + { + ArrayList list = getOrCreateList(key); + list.add(index, value); + } + + public void addAll(L key, Collection values) { + ArrayList list = getOrCreateList(key); + list.addAll(values); + } + + private ArrayList getOrCreateList(L key) + { + ArrayList list = (ArrayList) lists.get(key); + if (list==null) { + list = new ArrayList(1); + lists.put(key, list); + } + return list; + } + + private List getList(L key) + { + return lists.get(key); + } + + public boolean remove(L key, R value) + { + List list = getList(key); + if (list==null) return false; + boolean result = list.remove(value); + if (list.size()==0) + lists.remove(key); + return result; + } + + public boolean remove(L key) + { + List list = getList(key); + if (list==null) return false; + lists.remove(key); + return true; + } + + public void clear() + { + lists.clear(); + } + + public L[] getKeys(L[] list) + { + return lists.keySet().toArray(list); + } + + public Set getKeys() + { + return lists.keySet(); + } + + public int getKeySize() { + return lists.size(); + } + + public boolean containsKey(L key) + { + return lists.containsKey(key); + } + + public boolean contains(L key, R obj) + { + List l = lists.get(key); + if (l==null) return false; + return l.contains(obj); + + } + + public R[] getValues(L key, R[] list) + { + List l = lists.get(key); + if (l==null) return null; + return l.toArray(list); + } + + /** + * @param key + * the key to get values for + * @param list + * the list to fill with existing values for specified key. Fills + * this array with at maximum as many values as there is room for + * in the array even if there are more values available in the + * maplist for the specified key. + * @return the amount of values existing for the key. May be smaller or + * larger than the size of the provided list. If smaller, only the + * first array indexes will be filled with data and if larger, all + * array indexes will be filled with data. + */ + public int getAtMostValues(L key, R[] list) + { + List l = lists.get(key); + if (l==null) return 0; + int valueCount = l.size(); + int size = Math.min(valueCount, list.length); + for (int i = 0; i < size; ++i) + list[i] = l.get(i); + return valueCount; + } + + /** + * Returns a the internal list values for the specified key. The list is + * valid as long as it contains elements. The list should not be modified + * but the return value of this method does not enforce it like + * {@link #getValues(Object)} does. Use this method when you know you will + * not risk a 3rd party modifying the returned list and you want to avoid + * the cost of extra memory allocation through + * {@link Collections#unmodifiableList(List)}. + * + * @param key + * the key to look values for + * @return empty unmodifiable list if there is no list with the specified + * key, otherwise an unmodifiable version of the stored list + */ + public List getValuesUnsafe(L key) + { + List l = lists.get(key); + return l != null ? l : Collections.emptyList(); + } + + /** + * Returns a read-only reference to the values. The list is valid as long as + * it contains elements. + * + * @param key + * @return empty unmodifiable list if there is no list with the specified key, + * otherwise an unmodifiable version of the stored list + */ + public List getValues(L key) + { + List l = lists.get(key); + if (l==null) return Collections.emptyList(); + return Collections.unmodifiableList(l); + } + + /** + * Returns a copy of the values + * + * @param key + * @return empty unmodifiable list if there is no list with the specified key, + * otherwise a copy of the stored list + */ + public List getValuesSnapshot(L key) + { + List l = lists.get(key); + if (l==null) return Collections.emptyList(); + return new ArrayList(l); + } + + public List getAllValuesSnapshot() + { + return getAllValuesSnapshot(null); + } + + public List getAllValuesSnapshot(List result) + { + if (result == null) + result = new ArrayList(); + for (List right : lists.values()) { + result.addAll(right); + } + return result; + } + + public boolean isEmpty() { + return lists.isEmpty(); + } + + /** + * Makes _this_ maplist immutable. + */ + public void makeImmutable() { + for (Entry> e : lists.entrySet()) + lists.put(e.getKey(), Collections.unmodifiableList(e.getValue())); + lists = Collections.unmodifiableMap(lists); + } + +}