]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.graph/src/org/simantics/graph/representation/TransferableGraphQueries.java
Improve PrettyPrintTG performance
[simantics/platform.git] / bundles / org.simantics.graph / src / org / simantics / graph / representation / TransferableGraphQueries.java
diff --git a/bundles/org.simantics.graph/src/org/simantics/graph/representation/TransferableGraphQueries.java b/bundles/org.simantics.graph/src/org/simantics/graph/representation/TransferableGraphQueries.java
new file mode 100644 (file)
index 0000000..5d4c185
--- /dev/null
@@ -0,0 +1,205 @@
+package org.simantics.graph.representation;
+
+import java.util.Comparator;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import gnu.trove.impl.Constants;
+import gnu.trove.list.array.TIntArrayList;
+import gnu.trove.map.hash.TIntObjectHashMap;
+import gnu.trove.map.hash.TObjectIntHashMap;
+import gnu.trove.procedure.TObjectProcedure;
+
+public class TransferableGraphQueries {
+
+    private static final int NOT_FOUND = TransferableGraphUtils.NOT_FOUND;
+
+    private final TransferableGraph1 tg;
+
+    private final TIntObjectHashMap<Identity> internalIdentities = new TIntObjectHashMap<>(Constants.DEFAULT_CAPACITY, Constants.DEFAULT_LOAD_FACTOR, NOT_FOUND);
+    private final TIntObjectHashMap<Identity> externalIdentities = new TIntObjectHashMap<>(Constants.DEFAULT_CAPACITY, Constants.DEFAULT_LOAD_FACTOR, NOT_FOUND);
+    private final TIntObjectHashMap<Identity> rootIdentities = new TIntObjectHashMap<>(Constants.DEFAULT_CAPACITY, Constants.DEFAULT_LOAD_FACTOR, NOT_FOUND);
+
+    private final TObjectIntHashMap<String> internalIdentitiesByURI = new TObjectIntHashMap<>();
+    private final TObjectIntHashMap<String> externalIdentitiesByURI = new TObjectIntHashMap<>();
+    private final TObjectIntHashMap<String> rootIdentitiesByURI = new TObjectIntHashMap<>();
+
+    private final TIntObjectHashMap<TIntArrayList> statementsCache = new TIntObjectHashMap<>(Constants.DEFAULT_CAPACITY, Constants.DEFAULT_LOAD_FACTOR, NOT_FOUND);
+    
+    public TransferableGraphQueries(TransferableGraph1 graph) {
+        this.tg = graph;
+        
+        // Calculate internals
+        initializeIdentities();
+    }
+
+    private void initializeIdentities() {
+        for (Identity identity : tg.identities) {
+            IdentityDefinition definition = identity.definition;
+            if (definition instanceof Internal) {
+                Internal internal = (Internal) definition;
+                internalIdentities.put(identity.resource, identity);
+                internalIdentitiesByURI.put(getURI(identity), identity.resource);
+            } else if (definition instanceof External) {
+                External external = (External) definition;
+                externalIdentities.put(identity.resource, identity);
+                externalIdentitiesByURI.put(getURI(identity), identity.resource);
+            } else if (definition instanceof Root) {
+                Root root = (Root) definition;
+                rootIdentities.put(identity.resource, identity);
+                rootIdentitiesByURI.put(getURI(identity), identity.resource);
+            }
+        }
+    }
+
+    public String getURI(Identity identity) {
+        IdentityDefinition definition = identity.definition;
+        if(definition instanceof External) {
+            External def = (External)definition;
+            if(def.parent == -1) return "http:/";
+            else return getURI(def.parent) + "/" + def.name;
+        } else if(definition instanceof Root) {
+            Root def = (Root)definition;
+            if(def.name.isEmpty()) return "http:/";
+            return def.name;
+        } else if (definition instanceof Internal) {
+            Internal def = (Internal)definition;
+            return getURI(def.parent) + "/" + def.name;
+        } else {
+            return "";
+        }
+    }
+
+    public String getURI(int id) {
+        Identity identity = getIdentity(id);
+        if (identity == null)
+            return "<internal reference " + id + ">:";
+        return getURI(identity);
+    }
+
+    private static final Comparator<Identity> IDENTITY_NAME_COMPARATOR = new Comparator<Identity>() {
+        
+        @Override
+        public int compare(Identity o1, Identity o2) {
+            if (o1.definition instanceof Internal && o2.definition instanceof Internal) {
+                Internal i1 = (Internal) o1.definition; 
+                Internal i2 = (Internal) o2.definition;
+                return i1.name.compareTo(i2.name);
+            } else if (o1.definition instanceof External && o2.definition instanceof External) {
+                External e1 = (External) o1.definition;
+                External e2 = (External) o2.definition;
+                return e1.name.compareTo(e2.name);
+            } else {
+                throw new IllegalArgumentException(o1 + " " + o2);
+            }
+        }
+    };
+
+    public Set<Identity> getChildren(Identity parent) {
+        TreeSet<Identity> children = new TreeSet<>(IDENTITY_NAME_COMPARATOR);
+        internalIdentities.forEachEntry((resource, identity) -> {
+            Internal internal = (Internal) identity.definition;
+            if (internal.parent == parent.resource)
+                children.add(identity);
+            return true;
+        });
+        
+        return children;
+    }
+    
+    public Identity findInternalByName(String name) {
+        int internal = internalIdentitiesByURI.get(name);
+        if (internal == NOT_FOUND)
+            return null;
+        return internalIdentities.get(internal);
+    }
+
+    private Identity findExternalByName(String name) {
+        int external = externalIdentitiesByURI.get(name);
+        if (external == NOT_FOUND)
+            return null;
+        return externalIdentities.get(external);
+    }
+
+    private Identity findExternalByNameAndParent(String name, int parent) {
+        Identity external = findExternalByName(name);
+        if (external.resource == parent)
+            return external;
+        return null;
+    }
+
+    public Identity findExternalByURI(String uri) {
+        int v = externalIdentitiesByURI.get(uri);
+        if (v == NOT_FOUND)
+            return null;
+        return externalIdentities.get(v);
+    }
+
+    public Identity findRootByName(String name) {
+        int root = rootIdentitiesByURI.get(name);
+        if (root == NOT_FOUND)
+            return null;
+        return rootIdentities.get(root);
+    }
+    
+    public String getName(Identity identity) {
+        return TransferableGraphUtils.getName(identity);
+    }
+
+    public void forIdentities(TObjectProcedure<Identity> procedure) {
+        for (Identity identity : tg.identities) {
+            if (!procedure.execute(identity)) {
+                break;
+            }
+        }
+    }
+
+    public Identity getIdentity(int resource) {
+        Identity result = rootIdentities.get(resource);
+        if (result == null)
+            result = externalIdentities.get(resource);
+        if (result == null)
+            result = internalIdentities.get(resource);
+        return result;
+    }
+
+    public Value findValue(int object) {
+        return TransferableGraphUtils.findValue(tg, object);
+    }
+
+    public TreeMap<String, TreeSet<Integer>> sortByPredicateUniqueStatements(int resource) {
+        TreeMap<String, TreeSet<Integer>> results = new TreeMap<>();
+        TIntArrayList statements = getStatements(resource);
+        for (int i = 0; i < statements.size(); i += 2) {
+            int predicate = statements.get(i);
+            String predicateURI = getURI(predicate);
+            TreeSet<Integer> objects = results.get(predicateURI);
+            if (objects == null) {
+                objects = new TreeSet<>();
+            }
+            objects.add(statements.get(i + 1));
+            results.put(predicateURI, objects);
+        }
+        return results;
+    }
+
+    public TIntArrayList getStatements(int resource) {
+//        System.out.println("getting statements with " + resource);
+        TIntArrayList statements = statementsCache.get(resource);
+        if (statements == null) {
+            statements = TransferableGraphUtils.getStatements(tg, resource);
+            statementsCache.put(resource, statements);
+        }
+        return statements;
+    }
+
+    public int getPossibleObject(int subject, Identity predicate) {
+        return TransferableGraphUtils.getPossibleObject2(tg, subject, predicate);
+    }
+
+    public TransferableGraph1 getGraph() {
+        return tg;
+    }
+    
+}