]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/minigraph/Minigraph.java
Added missing parts from SVN org.simantics.root project.
[simantics/platform.git] / bundles / org.simantics.scl.runtime / src / org / simantics / scl / runtime / minigraph / Minigraph.java
1 package org.simantics.scl.runtime.minigraph;
2
3 import gnu.trove.impl.Constants;
4 import gnu.trove.map.hash.TIntObjectHashMap;
5 import gnu.trove.map.hash.TLongObjectHashMap;
6 import gnu.trove.map.hash.TObjectIntHashMap;
7 import gnu.trove.procedure.TIntProcedure;
8 import gnu.trove.set.hash.TIntHashSet;
9
10 import java.util.ArrayList;
11 import java.util.Collections;
12 import java.util.List;
13
14 import org.simantics.scl.runtime.SCLContext;
15 import org.simantics.scl.runtime.function.Function;
16 import org.simantics.scl.runtime.tuple.Tuple0;
17
18 public class Minigraph {
19
20     private static final int[] EMPTY_INT_ARRAY = new int[0];
21     
22     TIntObjectHashMap<TIntHashSet> predicatesPerSubject = new TIntObjectHashMap<TIntHashSet>();
23     TLongObjectHashMap<Object> objectsPerSubjectPredicate = new TLongObjectHashMap<Object>();
24     
25     TIntObjectHashMap<String> idToUri = new TIntObjectHashMap<String>();
26     TObjectIntHashMap<String> uriToId = new TObjectIntHashMap<String>(Constants.DEFAULT_CAPACITY,
27             Constants.DEFAULT_LOAD_FACTOR, -1);
28     TIntObjectHashMap<String> values = new TIntObjectHashMap<String>();
29     
30     int resourceCount = 0;
31     int InverseOf;
32
33     private static long combine(int a, int b) {
34         return (((long)a)<<32) | ((long)b);
35     }
36     
37     private static int[] toArray(Object obj) {
38         if(obj == null)
39             return EMPTY_INT_ARRAY;
40         else if(obj instanceof Integer)
41             return new int[] { (Integer)obj };
42         else
43             return ((TIntHashSet)obj).toArray();
44     }
45     
46     private static void add(TIntObjectHashMap<TIntHashSet> map, int key, int value) {
47         TIntHashSet set = map.get(key);
48         if(set == null) {
49             set = new TIntHashSet();
50             map.put(key, set);
51         }
52         set.add(value);
53     }
54     
55     private static void remove(TIntObjectHashMap<TIntHashSet> map, int key, int value) {
56         TIntHashSet set = map.get(key);
57         if(set != null)
58             set.remove(value);
59     }
60     
61     private static void add(TLongObjectHashMap<Object> map, long key, int value) {
62         Object obj = map.get(key);
63         if(obj == null)
64             map.put(key, Integer.valueOf(value));
65         else if(obj instanceof Integer) {
66             TIntHashSet set = new TIntHashSet();
67             set.add((Integer)obj);
68             set.add(value);
69             map.put(key, set);
70         }
71         else
72             ((TIntHashSet)obj).add(value);
73     }
74     
75     private static boolean remove(TLongObjectHashMap<Object> map, long key, int value) {
76         Object obj = map.get(key);
77         if(obj == null)
78             return false;
79         else if(obj instanceof Integer) {
80             if(value != ((Integer)obj).intValue())
81                 return false;
82             map.put(key, null);
83             return true;
84         }
85         else {
86             TIntHashSet set = (TIntHashSet)obj;
87             if(!set.remove(value))
88                 return false;
89             if(set.size() == 1)
90                 map.put(key, Integer.valueOf(set.iterator().next()));
91             return false;
92         }
93     }
94     
95     public int blank() {
96         return resourceCount++;
97     }
98     
99     public int getResource(String uri) {
100         int id = uriToId.get(uri);
101         if(id >= 0)
102             return id;
103         idToUri.put(resourceCount, uri);
104         uriToId.put(uri, resourceCount);
105         return resourceCount++;
106     }
107     
108     public String getUri(int r) {
109         String uri = idToUri.get(r);
110         if(uri != null)
111             return uri;
112         else
113             return "#" + r;
114     }
115     
116     public void rawClaim(int s, int p, int o) {
117         add(predicatesPerSubject, s, p);
118         add(objectsPerSubjectPredicate, combine(s, p), o);
119     }
120     
121     public void claim(int s, int p, int o) {
122         rawClaim(s, p, o);
123         int inv = getPossibleObject(p, InverseOf);
124         if(inv >= 0)
125             rawClaim(o, inv, s);
126     }
127     
128     public void rawDeny(int s, int p, int o) {
129         if(remove(objectsPerSubjectPredicate, combine(s, p), o))
130             remove(predicatesPerSubject, s, p);
131     }
132     
133     public void deny(int s, int p, int o) {
134         rawDeny(s, p, o);
135         int inv = getPossibleObject(p, InverseOf);
136         if(inv >= 0)
137             rawDeny(o, inv, s);
138     }
139     
140     public int[] getObjects(int s, int p) {
141         return toArray(objectsPerSubjectPredicate.get(combine(s, p)));
142     }
143     
144     public int[] getSubjects(int o, int p) {
145         int inv = getPossibleObject(p, InverseOf);
146         if(inv >= 0)
147             return getObjects(o, inv);
148         else
149             return EMPTY_INT_ARRAY;
150     }
151     
152     public int getPossibleObject(int s, int p) {
153         Object obj = objectsPerSubjectPredicate.get(combine(s, p));
154         if(obj instanceof Integer)
155             return ((Integer)obj).intValue();
156         else
157             return -1;
158     }
159     
160     public boolean hasStatement(int s, int p, int o) {
161         Object obj = objectsPerSubjectPredicate.get(combine(s, p));
162         if(obj == null)
163             return false;
164         else if(obj instanceof Integer)
165             return o == ((Integer)obj).intValue();
166         else 
167             return ((TIntHashSet)obj).contains(o);
168     }
169     
170     public List<Statement> getStatements(final int s) {
171         TIntHashSet preds = predicatesPerSubject.get(s);
172         if(preds == null)
173             return Collections.<Statement>emptyList();
174         
175         final ArrayList<Statement> statements = new ArrayList<Statement>();
176         preds.forEach(new TIntProcedure() {
177             @Override
178             public boolean execute(final int p) {
179                 Object obj = objectsPerSubjectPredicate.get(combine(s, p));
180                 if(obj instanceof Integer)
181                     statements.add(new Statement(s, p, (Integer)obj));
182                 else
183                     ((TIntHashSet)obj).forEach(new TIntProcedure() {
184                         @Override
185                         public boolean execute(int o) {
186                             statements.add(new Statement(s, p, o));
187                             return true;
188                         }
189                     });
190                 return true;
191             }
192         });
193         return statements;
194     }
195     
196     public void setValue(int s, String value) {
197         values.put(s, value);
198     }
199     
200     private void initializeLayer0() {
201         InverseOf = getResource("Layer0/InverseOf");
202         rawClaim(InverseOf, InverseOf, InverseOf);
203     }
204     
205     public Minigraph() {
206         initializeLayer0();
207     }
208     
209     public static void main(String[] args) {
210         Minigraph g = new Minigraph();
211         g.claim(10, g.InverseOf, 11);
212         g.claim(12, g.InverseOf, 13);
213         g.claim(1, 10, 2);
214         g.claim(1, 10, 3);
215         g.claim(1, 12, 4);
216         System.out.println(g.getStatements(2));
217     }
218
219     public static Object withGraph(Function f) {
220         Object oldGraph = SCLContext.getCurrent().put("graph", new Minigraph());
221         try {
222             return f.apply(Tuple0.INSTANCE);
223         } finally {
224             SCLContext.getCurrent().put("graph", oldGraph);
225         }
226     }
227 }