1 package org.simantics.graph.store;
\r
3 import gnu.trove.list.array.TIntArrayList;
\r
4 import gnu.trove.map.hash.TIntIntHashMap;
\r
5 import gnu.trove.map.hash.TIntObjectHashMap;
\r
6 import gnu.trove.procedure.TIntObjectProcedure;
\r
7 import gnu.trove.procedure.TIntProcedure;
\r
8 import gnu.trove.procedure.TObjectProcedure;
\r
9 import gnu.trove.set.hash.TIntHashSet;
\r
12 * Statement store indexes a set of statements.
\r
13 * @author Hannu Niemistö
\r
15 public class StatementStore implements IStore {
\r
17 static private final TIntArrayList EMPTY_INT_LIST = new TIntArrayList(0);
\r
19 TIntObjectHashMap<TIntObjectHashMap<TIntArrayList>> statements =
\r
20 new TIntObjectHashMap<TIntObjectHashMap<TIntArrayList>>();
\r
23 * Adds a statement to the store.
\r
28 public void add(int subject, int predicate, int object) {
\r
29 assert(subject >= 0);
\r
30 assert(predicate >= 0);
\r
31 assert(object >= 0);
\r
32 TIntObjectHashMap<TIntArrayList> localStatements =
\r
33 statements.get(subject);
\r
34 if(localStatements == null) {
\r
35 localStatements = new TIntObjectHashMap<TIntArrayList>(3);
\r
36 statements.put(subject, localStatements);
\r
38 TIntArrayList objects = localStatements.get(predicate);
\r
39 if(objects == null) {
\r
40 objects = new TIntArrayList(2);
\r
41 localStatements.put(predicate, objects);
\r
43 objects.add(object);
\r
46 public void map(final TIntIntHashMap map) {
\r
47 final TIntObjectHashMap<TIntObjectHashMap<TIntArrayList>> newStatements =
\r
48 new TIntObjectHashMap<TIntObjectHashMap<TIntArrayList>>(statements.size()*2+1);
\r
49 statements.forEachEntry(new TIntObjectProcedure<TIntObjectHashMap<TIntArrayList>>() {
\r
51 TIntObjectHashMap<TIntArrayList> newLocalStatements;
\r
52 TIntArrayList newObjects;
\r
54 TIntProcedure objectProcedure = new TIntProcedure() {
\r
56 public boolean execute(int o) {
\r
64 TIntObjectProcedure<TIntArrayList> predicateProcedure = new TIntObjectProcedure<TIntArrayList>() {
\r
66 public boolean execute(int p, TIntArrayList objects) {
\r
69 TIntArrayList exObjects = newLocalStatements.get(p);
\r
70 if(exObjects == null) {
\r
71 IndexMappingUtils.map(map, objects);
\r
72 newLocalStatements.put(p, objects);
\r
75 newObjects = exObjects;
\r
76 objects.forEach(objectProcedure);
\r
83 public boolean execute(int s, TIntObjectHashMap<TIntArrayList> localStatements) {
\r
86 TIntObjectHashMap<TIntArrayList> exLocalStatements = newStatements.get(s);
\r
87 if(exLocalStatements == null) {
\r
88 exLocalStatements = new TIntObjectHashMap<TIntArrayList>(localStatements.size()*2 + 1);
\r
89 newStatements.put(s, exLocalStatements);
\r
91 newLocalStatements = exLocalStatements;
\r
92 localStatements.forEachEntry(predicateProcedure);
\r
96 statements = newStatements;
\r
99 public void forStatements(final IStatementProcedure proc) {
\r
100 statements.forEachEntry(new TIntObjectProcedure<TIntObjectHashMap<TIntArrayList>>() {
\r
102 public boolean execute(final int s, TIntObjectHashMap<TIntArrayList> localStatements) {
\r
103 localStatements.forEachEntry(new TIntObjectProcedure<TIntArrayList>() {
\r
105 public boolean execute(final int p, TIntArrayList objects) {
\r
106 objects.forEach(new TIntProcedure() {
\r
108 public boolean execute(int o) {
\r
109 proc.execute(s, p, o);
\r
121 private static class ForStatementsWithSubjectProc implements TIntObjectProcedure<TIntArrayList>, TIntProcedure {
\r
124 IStatementProcedure proc;
\r
126 public ForStatementsWithSubjectProc(int s, IStatementProcedure proc) {
\r
132 public boolean execute(int o) {
\r
133 proc.execute(s, p, o);
\r
138 public boolean execute(int p, TIntArrayList b) {
\r
145 public void forStatementsWithSubject(int s, IStatementProcedure proc) {
\r
146 TIntObjectHashMap<TIntArrayList> localStatements = statements.get(s);
\r
147 if(localStatements == null)
\r
149 localStatements.forEachEntry(new ForStatementsWithSubjectProc(s, proc));
\r
152 public void forStatements(final int predicate, final IStatementProcedure proc) {
\r
153 statements.forEachEntry(new TIntObjectProcedure<TIntObjectHashMap<TIntArrayList>>() {
\r
155 public boolean execute(final int s, TIntObjectHashMap<TIntArrayList> localStatements) {
\r
156 TIntArrayList objects = localStatements.get(predicate);
\r
157 if(objects != null)
\r
158 objects.forEach(new TIntProcedure() {
\r
160 public boolean execute(int o) {
\r
161 proc.execute(s, predicate, o);
\r
170 public TIntArrayList getRelation(int predicate) {
\r
171 final TIntArrayList result = new TIntArrayList();
\r
172 forStatements(predicate, new IStatementProcedure() {
\r
174 public void execute(int s, int p, int o) {
\r
182 public TIntHashSet getRelationDomain(final int predicate) {
\r
183 final TIntHashSet result = new TIntHashSet();
\r
184 statements.forEachEntry(new TIntObjectProcedure<TIntObjectHashMap<TIntArrayList>>() {
\r
186 public boolean execute(int s, TIntObjectHashMap<TIntArrayList> localStatements) {
\r
187 if(localStatements.containsKey(predicate))
\r
195 public TIntArrayList extractRelation(final int predicate) {
\r
196 final TIntArrayList result = new TIntArrayList();
\r
197 final TIntArrayList removals = new TIntArrayList();
\r
198 statements.forEachEntry(new TIntObjectProcedure<TIntObjectHashMap<TIntArrayList>>() {
\r
200 public boolean execute(int s, TIntObjectHashMap<TIntArrayList> localStatements) {
\r
201 TIntArrayList objects = localStatements.remove(predicate);
\r
202 if(objects != null) {
\r
203 for(int o : objects.toArray()) {
\r
208 if(localStatements.isEmpty())
\r
213 for(int s : removals.toArray())
\r
214 statements.remove(s);
\r
218 public TIntArrayList getObjects(int subject, int predicate) {
\r
219 TIntObjectHashMap<TIntArrayList> localStatements = statements.get(subject);
\r
220 if(localStatements == null)
\r
221 return EMPTY_INT_LIST;
\r
222 TIntArrayList objects = localStatements.get(predicate);
\r
223 if(objects == null)
\r
224 return EMPTY_INT_LIST;
\r
228 public int[] toArray(final TIntIntHashMap inverseMap) {
\r
229 final TIntArrayList statements = new TIntArrayList();
\r
230 forStatements(new IStatementProcedure() {
\r
232 public void execute(int s, int p, int o) {
\r
236 if(inverseMap.contains(p)) {
\r
237 inverse = inverseMap.get(p);
\r
238 if(p==inverse && s == o)
\r
241 statements.add(inverse);
\r
242 statements.add(o);
\r
245 return statements.toArray();
\r
248 public void collectReferences(final boolean[] set) {
\r
249 forStatements(new IStatementProcedure() {
\r
251 public void execute(int s, int p, int o) {
\r
259 public TIntHashSet getPredicates() {
\r
260 final TIntHashSet result = new TIntHashSet();
\r
261 statements.forEachValue(new TObjectProcedure<TIntObjectHashMap<TIntArrayList>>() {
\r
262 TIntProcedure proc = new TIntProcedure() {
\r
264 public boolean execute(int value) {
\r
270 public boolean execute(TIntObjectHashMap<TIntArrayList> localStatements) {
\r
271 localStatements.forEachKey(proc);
\r
278 public int[] toArray() {
\r
279 final TIntArrayList statements = new TIntArrayList();
\r
280 forStatements(new IStatementProcedure() {
\r
282 public void execute(int s, int p, int o) {
\r
285 statements.add(-1);
\r
286 statements.add(o);
\r
289 return statements.toArray();
\r