]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/minigraph/Minigraph.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.runtime / src / org / simantics / scl / runtime / minigraph / Minigraph.java
diff --git a/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/minigraph/Minigraph.java b/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/minigraph/Minigraph.java
new file mode 100644 (file)
index 0000000..0a5b99d
--- /dev/null
@@ -0,0 +1,227 @@
+package org.simantics.scl.runtime.minigraph;
+
+import gnu.trove.impl.Constants;
+import gnu.trove.map.hash.TIntObjectHashMap;
+import gnu.trove.map.hash.TLongObjectHashMap;
+import gnu.trove.map.hash.TObjectIntHashMap;
+import gnu.trove.procedure.TIntProcedure;
+import gnu.trove.set.hash.TIntHashSet;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.simantics.scl.runtime.SCLContext;
+import org.simantics.scl.runtime.function.Function;
+import org.simantics.scl.runtime.tuple.Tuple0;
+
+public class Minigraph {
+
+    private static final int[] EMPTY_INT_ARRAY = new int[0];
+    
+    TIntObjectHashMap<TIntHashSet> predicatesPerSubject = new TIntObjectHashMap<TIntHashSet>();
+    TLongObjectHashMap<Object> objectsPerSubjectPredicate = new TLongObjectHashMap<Object>();
+    
+    TIntObjectHashMap<String> idToUri = new TIntObjectHashMap<String>();
+    TObjectIntHashMap<String> uriToId = new TObjectIntHashMap<String>(Constants.DEFAULT_CAPACITY,
+            Constants.DEFAULT_LOAD_FACTOR, -1);
+    TIntObjectHashMap<String> values = new TIntObjectHashMap<String>();
+    
+    int resourceCount = 0;
+    int InverseOf;
+
+    private static long combine(int a, int b) {
+        return (((long)a)<<32) | ((long)b);
+    }
+    
+    private static int[] toArray(Object obj) {
+        if(obj == null)
+            return EMPTY_INT_ARRAY;
+        else if(obj instanceof Integer)
+            return new int[] { (Integer)obj };
+        else
+            return ((TIntHashSet)obj).toArray();
+    }
+    
+    private static void add(TIntObjectHashMap<TIntHashSet> map, int key, int value) {
+        TIntHashSet set = map.get(key);
+        if(set == null) {
+            set = new TIntHashSet();
+            map.put(key, set);
+        }
+        set.add(value);
+    }
+    
+    private static void remove(TIntObjectHashMap<TIntHashSet> map, int key, int value) {
+        TIntHashSet set = map.get(key);
+        if(set != null)
+            set.remove(value);
+    }
+    
+    private static void add(TLongObjectHashMap<Object> map, long key, int value) {
+        Object obj = map.get(key);
+        if(obj == null)
+            map.put(key, Integer.valueOf(value));
+        else if(obj instanceof Integer) {
+            TIntHashSet set = new TIntHashSet();
+            set.add((Integer)obj);
+            set.add(value);
+            map.put(key, set);
+        }
+        else
+            ((TIntHashSet)obj).add(value);
+    }
+    
+    private static boolean remove(TLongObjectHashMap<Object> map, long key, int value) {
+        Object obj = map.get(key);
+        if(obj == null)
+            return false;
+        else if(obj instanceof Integer) {
+            if(value != ((Integer)obj).intValue())
+                return false;
+            map.put(key, null);
+            return true;
+        }
+        else {
+            TIntHashSet set = (TIntHashSet)obj;
+            if(!set.remove(value))
+                return false;
+            if(set.size() == 1)
+                map.put(key, Integer.valueOf(set.iterator().next()));
+            return false;
+        }
+    }
+    
+    public int blank() {
+        return resourceCount++;
+    }
+    
+    public int getResource(String uri) {
+        int id = uriToId.get(uri);
+        if(id >= 0)
+            return id;
+        idToUri.put(resourceCount, uri);
+        uriToId.put(uri, resourceCount);
+        return resourceCount++;
+    }
+    
+    public String getUri(int r) {
+        String uri = idToUri.get(r);
+        if(uri != null)
+            return uri;
+        else
+            return "#" + r;
+    }
+    
+    public void rawClaim(int s, int p, int o) {
+        add(predicatesPerSubject, s, p);
+        add(objectsPerSubjectPredicate, combine(s, p), o);
+    }
+    
+    public void claim(int s, int p, int o) {
+        rawClaim(s, p, o);
+        int inv = getPossibleObject(p, InverseOf);
+        if(inv >= 0)
+            rawClaim(o, inv, s);
+    }
+    
+    public void rawDeny(int s, int p, int o) {
+        if(remove(objectsPerSubjectPredicate, combine(s, p), o))
+            remove(predicatesPerSubject, s, p);
+    }
+    
+    public void deny(int s, int p, int o) {
+        rawDeny(s, p, o);
+        int inv = getPossibleObject(p, InverseOf);
+        if(inv >= 0)
+            rawDeny(o, inv, s);
+    }
+    
+    public int[] getObjects(int s, int p) {
+        return toArray(objectsPerSubjectPredicate.get(combine(s, p)));
+    }
+    
+    public int[] getSubjects(int o, int p) {
+        int inv = getPossibleObject(p, InverseOf);
+        if(inv >= 0)
+            return getObjects(o, inv);
+        else
+            return EMPTY_INT_ARRAY;
+    }
+    
+    public int getPossibleObject(int s, int p) {
+        Object obj = objectsPerSubjectPredicate.get(combine(s, p));
+        if(obj instanceof Integer)
+            return ((Integer)obj).intValue();
+        else
+            return -1;
+    }
+    
+    public boolean hasStatement(int s, int p, int o) {
+        Object obj = objectsPerSubjectPredicate.get(combine(s, p));
+        if(obj == null)
+            return false;
+        else if(obj instanceof Integer)
+            return o == ((Integer)obj).intValue();
+        else 
+            return ((TIntHashSet)obj).contains(o);
+    }
+    
+    public List<Statement> getStatements(final int s) {
+        TIntHashSet preds = predicatesPerSubject.get(s);
+        if(preds == null)
+            return Collections.<Statement>emptyList();
+        
+        final ArrayList<Statement> statements = new ArrayList<Statement>();
+        preds.forEach(new TIntProcedure() {
+            @Override
+            public boolean execute(final int p) {
+                Object obj = objectsPerSubjectPredicate.get(combine(s, p));
+                if(obj instanceof Integer)
+                    statements.add(new Statement(s, p, (Integer)obj));
+                else
+                    ((TIntHashSet)obj).forEach(new TIntProcedure() {
+                        @Override
+                        public boolean execute(int o) {
+                            statements.add(new Statement(s, p, o));
+                            return true;
+                        }
+                    });
+                return true;
+            }
+        });
+        return statements;
+    }
+    
+    public void setValue(int s, String value) {
+        values.put(s, value);
+    }
+    
+    private void initializeLayer0() {
+        InverseOf = getResource("Layer0/InverseOf");
+        rawClaim(InverseOf, InverseOf, InverseOf);
+    }
+    
+    public Minigraph() {
+        initializeLayer0();
+    }
+    
+    public static void main(String[] args) {
+        Minigraph g = new Minigraph();
+        g.claim(10, g.InverseOf, 11);
+        g.claim(12, g.InverseOf, 13);
+        g.claim(1, 10, 2);
+        g.claim(1, 10, 3);
+        g.claim(1, 12, 4);
+        System.out.println(g.getStatements(2));
+    }
+
+    public static Object withGraph(Function f) {
+        Object oldGraph = SCLContext.getCurrent().put("graph", new Minigraph());
+        try {
+            return f.apply(Tuple0.INSTANCE);
+        } finally {
+            SCLContext.getCurrent().put("graph", oldGraph);
+        }
+    }
+}