]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.graph/src/org/simantics/graph/store/StatementStore.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.graph / src / org / simantics / graph / store / StatementStore.java
diff --git a/bundles/org.simantics.graph/src/org/simantics/graph/store/StatementStore.java b/bundles/org.simantics.graph/src/org/simantics/graph/store/StatementStore.java
new file mode 100644 (file)
index 0000000..96b6b1c
--- /dev/null
@@ -0,0 +1,291 @@
+package org.simantics.graph.store;\r
+\r
+import gnu.trove.list.array.TIntArrayList;\r
+import gnu.trove.map.hash.TIntIntHashMap;\r
+import gnu.trove.map.hash.TIntObjectHashMap;\r
+import gnu.trove.procedure.TIntObjectProcedure;\r
+import gnu.trove.procedure.TIntProcedure;\r
+import gnu.trove.procedure.TObjectProcedure;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
+/**\r
+ * Statement store indexes a set of statements. \r
+ * @author Hannu Niemistö\r
+ */\r
+public class StatementStore implements IStore {\r
+       \r
+       static private final TIntArrayList EMPTY_INT_LIST = new TIntArrayList(0);       \r
+       \r
+       TIntObjectHashMap<TIntObjectHashMap<TIntArrayList>> statements =\r
+               new TIntObjectHashMap<TIntObjectHashMap<TIntArrayList>>();\r
+       \r
+       /**\r
+        * Adds a statement to the store.\r
+        * @param subject\r
+        * @param predicate\r
+        * @param object\r
+        */\r
+       public void add(int subject, int predicate, int object) {\r
+               assert(subject >= 0);\r
+               assert(predicate >= 0);\r
+               assert(object >= 0);\r
+               TIntObjectHashMap<TIntArrayList> localStatements = \r
+                       statements.get(subject);\r
+               if(localStatements == null) {\r
+                       localStatements = new TIntObjectHashMap<TIntArrayList>(3);\r
+                       statements.put(subject, localStatements);\r
+               }\r
+               TIntArrayList objects = localStatements.get(predicate);\r
+               if(objects == null) {\r
+                       objects = new TIntArrayList(2);\r
+                       localStatements.put(predicate, objects);\r
+               }\r
+               objects.add(object);\r
+       }\r
+       \r
+       public void map(final TIntIntHashMap map) {\r
+               final TIntObjectHashMap<TIntObjectHashMap<TIntArrayList>> newStatements = \r
+                       new TIntObjectHashMap<TIntObjectHashMap<TIntArrayList>>(statements.size()*2+1);\r
+               statements.forEachEntry(new TIntObjectProcedure<TIntObjectHashMap<TIntArrayList>>() {\r
+                       \r
+                       TIntObjectHashMap<TIntArrayList> newLocalStatements;\r
+                       TIntArrayList newObjects;\r
+                       \r
+                       TIntProcedure objectProcedure = new TIntProcedure() {                                                           \r
+                               @Override\r
+                               public boolean execute(int o) {\r
+                                       if(map.contains(o))\r
+                                               o = map.get(o);\r
+                                       newObjects.add(o);\r
+                                       return true;\r
+                               }\r
+                       };\r
+                       \r
+                       TIntObjectProcedure<TIntArrayList> predicateProcedure = new TIntObjectProcedure<TIntArrayList>() {\r
+                               @Override\r
+                               public boolean execute(int p, TIntArrayList objects) {\r
+                                       if(map.contains(p))\r
+                                               p = map.get(p);\r
+                                       TIntArrayList exObjects = newLocalStatements.get(p);\r
+                                       if(exObjects == null) {\r
+                                               IndexMappingUtils.map(map, objects);\r
+                                               newLocalStatements.put(p, objects);\r
+                                       }\r
+                                       else {\r
+                                               newObjects = exObjects;\r
+                                               objects.forEach(objectProcedure);\r
+                                       }\r
+                                       return true;\r
+                               }\r
+                       };\r
+                       \r
+                       @Override\r
+                       public boolean execute(int s, TIntObjectHashMap<TIntArrayList> localStatements) {\r
+                               if(map.contains(s))\r
+                                       s = map.get(s);\r
+                               TIntObjectHashMap<TIntArrayList> exLocalStatements = newStatements.get(s);                              \r
+                               if(exLocalStatements == null) {\r
+                                       exLocalStatements = new TIntObjectHashMap<TIntArrayList>(localStatements.size()*2 + 1);\r
+                                       newStatements.put(s, exLocalStatements);\r
+                               }\r
+                               newLocalStatements = exLocalStatements;\r
+                               localStatements.forEachEntry(predicateProcedure);\r
+                               return true;\r
+                       }\r
+               });\r
+               statements = newStatements;\r
+       }\r
+       \r
+       public void forStatements(final IStatementProcedure proc) {\r
+               statements.forEachEntry(new TIntObjectProcedure<TIntObjectHashMap<TIntArrayList>>() {\r
+                       @Override\r
+                       public boolean execute(final int s, TIntObjectHashMap<TIntArrayList> localStatements) {\r
+                               localStatements.forEachEntry(new TIntObjectProcedure<TIntArrayList>() {\r
+                                       @Override\r
+                                       public boolean execute(final int p, TIntArrayList objects) {\r
+                                               objects.forEach(new TIntProcedure() {                                                   \r
+                                                       @Override\r
+                                                       public boolean execute(int o) {\r
+                                                               proc.execute(s, p, o);\r
+                                                               return true;\r
+                                                       }\r
+                                               });\r
+                                               return true;\r
+                                       }\r
+                               });\r
+                               return true;\r
+                       }\r
+               });\r
+       }\r
+       \r
+       private static class ForStatementsWithSubjectProc implements TIntObjectProcedure<TIntArrayList>, TIntProcedure {\r
+               int s;\r
+               int p;\r
+               IStatementProcedure proc;\r
+               \r
+               public ForStatementsWithSubjectProc(int s, IStatementProcedure proc) {\r
+                       this.s = s;\r
+                       this.proc = proc;\r
+               }\r
+\r
+               @Override\r
+               public boolean execute(int o) {\r
+                       proc.execute(s, p, o);\r
+                       return true;\r
+               }\r
+\r
+               @Override\r
+               public boolean execute(int p, TIntArrayList b) {\r
+                       this.p = p;\r
+                       b.forEach(this);\r
+                       return true;\r
+               }               \r
+       }\r
+       \r
+       public void forStatementsWithSubject(int s, IStatementProcedure proc) {\r
+               TIntObjectHashMap<TIntArrayList> localStatements = statements.get(s);\r
+               if(localStatements == null)\r
+                       return;\r
+               localStatements.forEachEntry(new ForStatementsWithSubjectProc(s, proc));\r
+       }\r
+       \r
+       public void forStatements(final int predicate, final IStatementProcedure proc) {\r
+               statements.forEachEntry(new TIntObjectProcedure<TIntObjectHashMap<TIntArrayList>>() {\r
+                       @Override\r
+                       public boolean execute(final int s, TIntObjectHashMap<TIntArrayList> localStatements) {\r
+                               TIntArrayList objects = localStatements.get(predicate);\r
+                               if(objects != null)\r
+                                       objects.forEach(new TIntProcedure() {                                                   \r
+                                                       @Override\r
+                                                       public boolean execute(int o) {\r
+                                                               proc.execute(s, predicate, o);\r
+                                                               return true;\r
+                                                       }\r
+                                               });                                             \r
+                               return true;\r
+                       }\r
+               });\r
+       }\r
+       \r
+       public TIntArrayList getRelation(int predicate) {\r
+               final TIntArrayList result = new TIntArrayList();\r
+               forStatements(predicate, new IStatementProcedure() {                    \r
+                       @Override\r
+                       public void execute(int s, int p, int o) {\r
+                               result.add(s);\r
+                               result.add(o);\r
+                       }\r
+               });\r
+               return result;\r
+       }\r
+       \r
+       public TIntHashSet getRelationDomain(final int predicate) {\r
+               final TIntHashSet result = new TIntHashSet();\r
+               statements.forEachEntry(new TIntObjectProcedure<TIntObjectHashMap<TIntArrayList>>() {\r
+                       @Override\r
+                       public boolean execute(int s, TIntObjectHashMap<TIntArrayList> localStatements) {\r
+                               if(localStatements.containsKey(predicate))\r
+                                       result.add(s);\r
+                               return true;\r
+                       }\r
+               });\r
+               return result;\r
+       }\r
+       \r
+       public TIntArrayList extractRelation(final int predicate) {\r
+               final TIntArrayList result = new TIntArrayList();\r
+               final TIntArrayList removals = new TIntArrayList();\r
+               statements.forEachEntry(new TIntObjectProcedure<TIntObjectHashMap<TIntArrayList>>() {\r
+                       @Override\r
+                       public boolean execute(int s, TIntObjectHashMap<TIntArrayList> localStatements) {\r
+                               TIntArrayList objects = localStatements.remove(predicate);\r
+                               if(objects != null) {\r
+                                       for(int o : objects.toArray()) {\r
+                                               result.add(s);\r
+                                               result.add(o);\r
+                                       }\r
+                               }\r
+                               if(localStatements.isEmpty())\r
+                                       removals.add(s);\r
+                               return true;\r
+                       }\r
+               });\r
+               for(int s : removals.toArray())\r
+                       statements.remove(s);\r
+               return result;\r
+       }\r
+       \r
+       public TIntArrayList getObjects(int subject, int predicate) {\r
+               TIntObjectHashMap<TIntArrayList> localStatements = statements.get(subject);\r
+               if(localStatements == null)\r
+                       return EMPTY_INT_LIST;\r
+               TIntArrayList objects = localStatements.get(predicate);\r
+               if(objects == null)\r
+                       return EMPTY_INT_LIST;\r
+               return objects;\r
+       }\r
+\r
+       public int[] toArray(final TIntIntHashMap inverseMap) {\r
+               final TIntArrayList statements = new TIntArrayList();\r
+               forStatements(new IStatementProcedure() {                       \r
+                       @Override\r
+                       public void execute(int s, int p, int o) {\r
+                               statements.add(s);\r
+                               statements.add(p);\r
+                               int inverse = -1;\r
+                               if(inverseMap.contains(p)) {\r
+                                       inverse = inverseMap.get(p);\r
+                                       if(p==inverse && s == o)\r
+                                               inverse = -1;\r
+                               }\r
+                               statements.add(inverse);\r
+                               statements.add(o);                              \r
+                       }\r
+               });\r
+               return statements.toArray();\r
+       }\r
+       \r
+       public void collectReferences(final boolean[] set) {\r
+               forStatements(new IStatementProcedure() {                       \r
+                       @Override\r
+                       public void execute(int s, int p, int o) {\r
+                               set[s] = true;\r
+                               set[p] = true;\r
+                               set[o] = true;          \r
+                       }\r
+               });\r
+       }\r
+\r
+       public TIntHashSet getPredicates() {\r
+               final TIntHashSet result = new TIntHashSet();\r
+               statements.forEachValue(new TObjectProcedure<TIntObjectHashMap<TIntArrayList>>() {                      \r
+                       TIntProcedure proc = new TIntProcedure() {                              \r
+                               @Override\r
+                               public boolean execute(int value) {\r
+                                       result.add(value);\r
+                                       return true;\r
+                               }\r
+                       };                      \r
+                       @Override\r
+                       public boolean execute(TIntObjectHashMap<TIntArrayList> localStatements) {\r
+                               localStatements.forEachKey(proc);\r
+                               return true;\r
+                       }\r
+               });\r
+               return result;\r
+       }\r
+\r
+       public int[] toArray() {\r
+               final TIntArrayList statements = new TIntArrayList();\r
+               forStatements(new IStatementProcedure() {                       \r
+                       @Override\r
+                       public void execute(int s, int p, int o) {\r
+                               statements.add(s);\r
+                               statements.add(p);\r
+                               statements.add(-1);\r
+                               statements.add(o);                              \r
+                       }\r
+               });\r
+               return statements.toArray();\r
+       }       \r
+}\r