X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.utils.datastructures%2Fsrc%2Forg%2Fsimantics%2Futils%2Fdatastructures%2Fmap%2FAssociativeMap.java;h=cd2cdd2b8c6ccc2f1bba3efaed674ca51b5be3c3;hb=refs%2Fchanges%2F38%2F238%2F2;hp=97ae6ad8807ebb16d0e2ce62fc33c05d0abde67b;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.utils.datastructures/src/org/simantics/utils/datastructures/map/AssociativeMap.java b/bundles/org.simantics.utils.datastructures/src/org/simantics/utils/datastructures/map/AssociativeMap.java index 97ae6ad88..cd2cdd2b8 100644 --- a/bundles/org.simantics.utils.datastructures/src/org/simantics/utils/datastructures/map/AssociativeMap.java +++ b/bundles/org.simantics.utils.datastructures/src/org/simantics/utils/datastructures/map/AssociativeMap.java @@ -1,194 +1,194 @@ -/******************************************************************************* - * 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.map; - -import gnu.trove.map.hash.THashMap; -import gnu.trove.set.hash.THashSet; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; - -/** - * Associative map of n-tuples. Tuple is the primitive of this data structure. - * It describes an association between objects. - * The number of fields in each tuple must match the level of associativity. - *

- * Associative map allows quick queries of tuples by pre-indexing its content. - * Indexing requires that the object is told ahead which combinations of fields - * to cache. Each combination is described with {@link Associativity} object - * at construction, and for each description a new hashmap is created. - * - * Example, fully associative map for 4-tuples, use - * - * AssociativeMap map = new AssociativeMap( Associativity.fullAssociativity( 4 ) ); - * map.addStatements( new Tuple( cluster, subject, predicate, object ) ); - * - * Example, BijectionMap - * - * AssociativeMap bijectionMap = - * new AssociativeMap( new Associativity(false, true), new Associativity(true, false) ) - * - * bijectionMap.addStatements( new Tuple("x", "y") ); - *

- * Queries are described with {@link Tuple}-instances. null value describes - * open ended value and actual object restriction. - * - * Example, query for all Tuples with "x" as the first argument: - * - * bijectionMap.getStatements(new Tuple("x", null), null);; - * - * @see Associativity - * @see Tuple - * @author Toni Kalajainen - */ -public class AssociativeMap { - - /** Number of dimensions */ - int level; - /** Maps sorted by TupleQueryAssociativity, TupleQuery, Tuples */ - THashMap> [] maps; - /** Tuple query for all statements */ - Tuple tupleQueryAllTuples; - /** Associativities */ - Associativity[] associativities; - - /** - * Create partially associative map of n-tuples. - * - * @param associativenesses - */ - @SuppressWarnings("unchecked") - public AssociativeMap(Associativity ... associativenesses) - { - if (associativenesses==null) throw new NullPointerException(); - if (associativenesses.length==0) throw new IllegalArgumentException(); - this.associativities = associativenesses; - level = associativenesses[0].getLevel(); - for (int i=1; i> map = new THashMap>(); - maps[associativity] = map; - } - tupleQueryAllTuples = new Tuple(new Object[level]); - } - - public void add(Collection stms) - { - for (int associativity=0; associativity> map = maps[associativity]; - if (map==null) continue; - for (Tuple stm : stms) { - if (!stm.isFull()) throw new IllegalArgumentException("Tuple Query cannot be added."); - Tuple tupleQuery = createTupleQuery(stm, associativity); - THashSet set = map.get(tupleQuery); - if (set==null) map.put(tupleQuery, set = new THashSet()); - set.add(stm); - } - } - } - - public void add(Tuple...stms) - { - for (int associativity=0; associativity> map = maps[associativity]; - if (map==null) continue; - for (Tuple stm : stms) { - if (!stm.isFull()) throw new IllegalArgumentException("Tuple Query cannot be added."); - Tuple tupleQuery = createTupleQuery(stm, associativity); - THashSet set = map.get(tupleQuery); - if (set==null) map.put(tupleQuery, set = new THashSet()); - set.add(stm); - } - } - } - - public void remove(Collection stms) { - for (int associativity=0; associativity> map = maps[associativity]; - if (map==null) continue; - for (Tuple stm : stms) { - Tuple tupleQuery = createTupleQuery(stm, associativity); - THashSet set = map.get(tupleQuery); - if (set==null) continue; - set.remove(stm); - } - } - } - - public Collection get(Tuple tupleQuery, Collection result) - throws UnsupportedOperationException - { - if (tupleQuery ==null || tupleQuery.getLevel() != level) throw new IllegalArgumentException(); - - /** Special case, query for existance of a specific tuple */ - if (tupleQuery.associativity == maps.length) { - THashMap> map = maps[0]; - if (map==null) throw new UnsupportedOperationException(); - THashSet set = map.get(tupleQueryAllTuples); - if (result == null) { - if (set!=null && set.contains(tupleQuery)) - return Collections.singleton(tupleQuery); - else - return Collections.emptySet(); - } else { - if (set.contains(tupleQuery)) - result.add(tupleQuery); - return result; - } - } - - THashMap> map = maps[tupleQuery.associativity]; - if (map==null) throw new UnsupportedOperationException(); - THashSet set = map.get(tupleQuery); - if (set==null) return Collections.emptySet(); - if (result == null) result = new ArrayList(set.size()); - for (Tuple t : set) - result.add(t); - return result; - } - - public Associativity[] getAssociativities() { - return associativities; - } - - private static Tuple createTupleQuery(Tuple tuple, int associativity) - { - if (tuple.associativity == associativity) return tuple; - int mask = 1; - int level = tuple.getLevel(); - Object fields[] = new Object[level]; - for (int i=0; i0) - fields[i] = tuple.getField(i); - mask <<= 1; - } - return new Tuple(fields); - } - - public int getLevel() { - return level; - } - -} - +/******************************************************************************* + * 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.map; + +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; + +/** + * Associative map of n-tuples. Tuple is the primitive of this data structure. + * It describes an association between objects. + * The number of fields in each tuple must match the level of associativity. + *

+ * Associative map allows quick queries of tuples by pre-indexing its content. + * Indexing requires that the object is told ahead which combinations of fields + * to cache. Each combination is described with {@link Associativity} object + * at construction, and for each description a new hashmap is created. + * + * Example, fully associative map for 4-tuples, use + * + * AssociativeMap map = new AssociativeMap( Associativity.fullAssociativity( 4 ) ); + * map.addStatements( new Tuple( cluster, subject, predicate, object ) ); + * + * Example, BijectionMap + * + * AssociativeMap bijectionMap = + * new AssociativeMap( new Associativity(false, true), new Associativity(true, false) ) + * + * bijectionMap.addStatements( new Tuple("x", "y") ); + *

+ * Queries are described with {@link Tuple}-instances. null value describes + * open ended value and actual object restriction. + * + * Example, query for all Tuples with "x" as the first argument: + * + * bijectionMap.getStatements(new Tuple("x", null), null);; + * + * @see Associativity + * @see Tuple + * @author Toni Kalajainen + */ +public class AssociativeMap { + + /** Number of dimensions */ + int level; + /** Maps sorted by TupleQueryAssociativity, TupleQuery, Tuples */ + THashMap> [] maps; + /** Tuple query for all statements */ + Tuple tupleQueryAllTuples; + /** Associativities */ + Associativity[] associativities; + + /** + * Create partially associative map of n-tuples. + * + * @param associativenesses + */ + @SuppressWarnings("unchecked") + public AssociativeMap(Associativity ... associativenesses) + { + if (associativenesses==null) throw new NullPointerException(); + if (associativenesses.length==0) throw new IllegalArgumentException(); + this.associativities = associativenesses; + level = associativenesses[0].getLevel(); + for (int i=1; i> map = new THashMap>(); + maps[associativity] = map; + } + tupleQueryAllTuples = new Tuple(new Object[level]); + } + + public void add(Collection stms) + { + for (int associativity=0; associativity> map = maps[associativity]; + if (map==null) continue; + for (Tuple stm : stms) { + if (!stm.isFull()) throw new IllegalArgumentException("Tuple Query cannot be added."); + Tuple tupleQuery = createTupleQuery(stm, associativity); + THashSet set = map.get(tupleQuery); + if (set==null) map.put(tupleQuery, set = new THashSet()); + set.add(stm); + } + } + } + + public void add(Tuple...stms) + { + for (int associativity=0; associativity> map = maps[associativity]; + if (map==null) continue; + for (Tuple stm : stms) { + if (!stm.isFull()) throw new IllegalArgumentException("Tuple Query cannot be added."); + Tuple tupleQuery = createTupleQuery(stm, associativity); + THashSet set = map.get(tupleQuery); + if (set==null) map.put(tupleQuery, set = new THashSet()); + set.add(stm); + } + } + } + + public void remove(Collection stms) { + for (int associativity=0; associativity> map = maps[associativity]; + if (map==null) continue; + for (Tuple stm : stms) { + Tuple tupleQuery = createTupleQuery(stm, associativity); + THashSet set = map.get(tupleQuery); + if (set==null) continue; + set.remove(stm); + } + } + } + + public Collection get(Tuple tupleQuery, Collection result) + throws UnsupportedOperationException + { + if (tupleQuery ==null || tupleQuery.getLevel() != level) throw new IllegalArgumentException(); + + /** Special case, query for existance of a specific tuple */ + if (tupleQuery.associativity == maps.length) { + THashMap> map = maps[0]; + if (map==null) throw new UnsupportedOperationException(); + THashSet set = map.get(tupleQueryAllTuples); + if (result == null) { + if (set!=null && set.contains(tupleQuery)) + return Collections.singleton(tupleQuery); + else + return Collections.emptySet(); + } else { + if (set.contains(tupleQuery)) + result.add(tupleQuery); + return result; + } + } + + THashMap> map = maps[tupleQuery.associativity]; + if (map==null) throw new UnsupportedOperationException(); + THashSet set = map.get(tupleQuery); + if (set==null) return Collections.emptySet(); + if (result == null) result = new ArrayList(set.size()); + for (Tuple t : set) + result.add(t); + return result; + } + + public Associativity[] getAssociativities() { + return associativities; + } + + private static Tuple createTupleQuery(Tuple tuple, int associativity) + { + if (tuple.associativity == associativity) return tuple; + int mask = 1; + int level = tuple.getLevel(); + Object fields[] = new Object[level]; + for (int i=0; i0) + fields[i] = tuple.getField(i); + mask <<= 1; + } + return new Tuple(fields); + } + + public int getLevel() { + return level; + } + +} +