]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/CollectionSupportImpl.java
Merge branch 'feature/funcwrite'
[simantics/platform.git] / bundles / org.simantics.db.procore / src / fi / vtt / simantics / procore / internal / CollectionSupportImpl.java
1 package fi.vtt.simantics.procore.internal;
2
3 import java.lang.reflect.Array;
4 import java.util.ArrayList;
5 import java.util.Collection;
6 import java.util.Collections;
7 import java.util.Comparator;
8 import java.util.HashSet;
9 import java.util.Iterator;
10 import java.util.List;
11 import java.util.ListIterator;
12 import java.util.Map;
13 import java.util.Set;
14
15 import org.simantics.db.ReadGraph;
16 import org.simantics.db.Resource;
17 import org.simantics.db.Statement;
18 import org.simantics.db.exception.ResourceNotFoundException;
19 import org.simantics.db.impl.ResourceImpl;
20 import org.simantics.db.impl.graph.ReadGraphImpl;
21 import org.simantics.db.impl.query.IntSet;
22 import org.simantics.db.service.CollectionSupport;
23 import org.simantics.utils.datastructures.Callback;
24
25 import gnu.trove.impl.Constants;
26 import gnu.trove.iterator.TIntIterator;
27 import gnu.trove.list.array.TIntArrayList;
28 import gnu.trove.map.hash.TIntIntHashMap;
29 import gnu.trove.map.hash.TIntObjectHashMap;
30 import gnu.trove.map.hash.TObjectIntHashMap;
31 import gnu.trove.procedure.TIntObjectProcedure;
32 import gnu.trove.procedure.TIntProcedure;
33 import gnu.trove.procedure.TObjectIntProcedure;
34 import gnu.trove.procedure.TObjectProcedure;
35 import gnu.trove.set.hash.TIntHashSet;
36
37 public class CollectionSupportImpl implements CollectionSupport {
38         
39         final private SessionImplSocket session;
40         
41         CollectionSupportImpl(SessionImplSocket session) {
42                 this.session = session;
43         }
44         
45         static final class IntResourceMap {
46         
47                 final private SessionImplSocket session;
48                 final private TIntIntHashMap backend = new TIntIntHashMap(Constants.DEFAULT_CAPACITY, Constants.DEFAULT_LOAD_FACTOR, -1, 0);
49                 
50                 IntResourceMap(SessionImplSocket session) {
51                         this.session = session;
52                 }
53                 
54                 public int size() {
55                         return backend.size();
56                 }
57                 
58                 public boolean isEmpty() {
59                         return backend.isEmpty();
60                 }
61                 
62                 public boolean containsKey(int key) {
63                         return backend.containsKey(key);
64                 }
65                 
66                 public boolean containsValue(int value) {
67                         return backend.containsValue(value);
68                 }
69                 
70                 public Resource get(int key) {
71                         try {
72                                 return session.getResourceByKey(backend.get(key));
73                         } catch (ResourceNotFoundException e) {
74                                 e.printStackTrace();
75                         }
76                         return null;
77                 }
78                 
79                 public Resource put(int key, Resource value) {
80                         ResourceImpl impl = (ResourceImpl) value;
81                         int i = backend.put(key, impl.id);
82                         if (i == 0)
83                                 return null;
84                         else
85                                 try {
86                                         return session.getResourceByKey(i);
87                                 } catch (ResourceNotFoundException e) {
88                                         e.printStackTrace();
89                                 }
90                         return null;
91                 }
92                 
93                 public Resource remove(int key) {
94                         throw new UnsupportedOperationException("remove not supported");
95                 }
96
97                 @Override
98                 public int hashCode() {
99                         return backend.hashCode();
100                 }
101
102                 @Override
103                 public boolean equals(Object obj) {
104                         if (this == obj)
105                                 return true;
106                         if (obj == null)
107                                 return false;
108                         if (getClass() != obj.getClass())
109                                 return false;
110                         IntResourceMap other = (IntResourceMap) obj;
111                         return session == other.session && backend.equals(other.backend);
112                 }
113         }
114         
115         public IntResourceMap createIntResourceMap() {
116                 return new IntResourceMap(session);
117         }
118
119         static final class ObjectResourceMap<T> implements Map<T, Resource> {
120                 
121                 final private SessionImplSocket session;
122                 final private TObjectIntHashMap<T> backend;
123                 
124                 ObjectResourceMap(SessionImplSocket session) {
125                         this.session = session;
126                         backend = new TObjectIntHashMap<T>(Constants.DEFAULT_CAPACITY, Constants.DEFAULT_LOAD_FACTOR, 0);
127                 }
128
129                 ObjectResourceMap(SessionImplSocket session, int capacity) {
130                         this.session = session;
131                         backend = new TObjectIntHashMap<T>(capacity, Constants.DEFAULT_LOAD_FACTOR, 0);
132                 }
133                 
134                 @Override
135                 public int size() {
136                         return backend.size();
137                 }
138                 @Override
139                 public boolean isEmpty() {
140                         return backend.isEmpty();
141                 }
142                 
143                 @Override
144                 public boolean containsKey(Object key) {
145                         return backend.contains(key);
146                 }
147                 
148                 @Override
149                 public boolean containsValue(Object value) {
150                         ResourceImpl impl = (ResourceImpl) value;
151                         return backend.containsValue(impl.id);
152                 }
153                 
154                 @Override
155                 public Resource get(Object key) {
156                         try {
157                                 int result = backend.get(key);
158                                 if (result == 0)
159                                         return null;
160                                 return session.getResourceByKey(result);
161                         } catch (ResourceNotFoundException e) {
162                                 e.printStackTrace();
163                         }
164                         return null;
165                 }
166                 
167                 @Override
168                 public Resource put(T key, Resource value) {
169                         ResourceImpl impl = (ResourceImpl) value;
170                         int i = backend.put(key, impl.id);
171                         if (i == 0)
172                                 return null;
173                         else
174                                 try {
175                                         return session.getResourceByKey(i);
176                                 } catch (ResourceNotFoundException e) {
177                                         e.printStackTrace();
178                                 }
179                         return null;
180                 }
181                 
182                 @Override
183                 public Resource remove(Object key) {
184                         throw new UnsupportedOperationException("remove not supported, structure is immutable");
185                 }
186                 
187                 @Override
188                 public void putAll(Map<? extends T, ? extends Resource> map) {
189                         @SuppressWarnings("unchecked")
190                         ObjectResourceMap<T> other = (ObjectResourceMap<T>) map;
191                         other.backend.forEachEntry(new TObjectIntProcedure<T>() {
192
193                                 @Override
194                                 public boolean execute(T a, int b) {
195                                         backend.put(a, b);
196                                         return true;
197                                 }
198                         });
199                 }
200                 
201                 @Override
202                 public void clear() {
203                         throw new UnsupportedOperationException("clear not supported, structure is immutable");
204                 }
205                 
206                 @Override
207                 public Set<T> keySet() {
208                         final Set<T> result = new HashSet<T>();
209                         backend.forEach(new TObjectProcedure<T>() {
210
211                                 @Override
212                                 public boolean execute(T object) {
213                                         result.add(object);
214                                         return true;
215                                 }
216                         });
217                         return result;
218                 }
219                 
220                 @Override
221                 public Collection<Resource> values() {
222                         ArrayList<Resource> result = new ArrayList<Resource>();
223                         for (int key : backend.values()) {
224                                 try {
225                                         result.add(session.getResourceByKey(key));
226                                 } catch (ResourceNotFoundException e) {
227                                         e.printStackTrace();
228                                 }
229                         }
230                         return result;
231                 }
232                 
233                 @Override
234                 public Set<java.util.Map.Entry<T, Resource>> entrySet() {
235                         final HashSet<java.util.Map.Entry<T, Resource>> result = new HashSet<java.util.Map.Entry<T, Resource>>();
236                         backend.forEachEntry(new TObjectIntProcedure<T>() {
237
238                                 @Override
239                                 public boolean execute(final T a, final int b) {
240                                         return result.add(new Map.Entry<T, Resource>() {
241
242                                                 @Override
243                                                 public T getKey() {
244                                                         return a;
245                                                 }
246
247                                                 @Override
248                                                 public Resource getValue() {
249                                                         return new ResourceImpl(session.resourceSupport, b);
250                                                 }
251
252                                                 @Override
253                                                 public Resource setValue(Resource value) {
254                                                         throw new UnsupportedOperationException("Map.Entry.setValue not supported, structure is immutable");
255                                                 }
256                                                 
257                                         });
258                                 }
259                         });
260                         return result;
261                 }
262
263                 @Override
264                 public int hashCode() {
265                         return backend.hashCode();
266                 }
267
268                 @Override
269                 public boolean equals(Object obj) {
270                         if (this == obj)
271                                 return true;
272                         if (obj == null)
273                                 return false;
274                         if (getClass() != obj.getClass())
275                                 return false;
276                         ObjectResourceMap<?> other = (ObjectResourceMap<?>) obj;
277                         return session == other.session && backend.equals(other.backend);
278                 }
279
280         }
281         
282         @SuppressWarnings("unchecked")
283         @Override
284         public <T, I> T createObjectResourceMap(Class<I> clazz) {
285                 return (T)new ObjectResourceMap<I>(session);
286         }
287
288         @SuppressWarnings("unchecked")
289         @Override
290         public <T, I> T createObjectResourceMap(Class<I> clazz, int capacity) {
291                 return (T)new ObjectResourceMap<I>(session, capacity);
292         }
293
294     static final class ResourceMap<T> implements org.simantics.db.ResourceMap<T> {
295         
296         final private SessionImplSocket session;
297         final private TIntObjectHashMap<T> backend = new TIntObjectHashMap<T>();
298
299         ResourceMap(SessionImplSocket session) {
300                 this.session = session;
301         }
302         
303                 @Override
304                 public void clear() {
305                         throw new UnsupportedOperationException("Not implemented");
306                 }
307
308                 @Override
309                 public boolean containsKey(Object resource) {
310                         ResourceImpl impl = (ResourceImpl)resource;
311                         return backend.containsKey(impl.id);
312                 }
313
314                 @SuppressWarnings("unchecked")
315                 @Override
316                 public boolean containsValue(Object value) {
317                         return backend.containsValue((T)value);
318                 }
319
320                 @Override
321                 public Set<java.util.Map.Entry<Resource, T>> entrySet() {
322                         final HashSet<java.util.Map.Entry<Resource, T>> result = new HashSet<java.util.Map.Entry<Resource, T>>();
323                         backend.forEachEntry(new TIntObjectProcedure<T>() {
324
325                                 @Override
326                                 public boolean execute(final int a, final T b) {
327                                         result.add(new Map.Entry<Resource, T>() {
328
329                                                 @Override
330                                                 public Resource getKey() {
331                                                         return new ResourceImpl(session.resourceSupport, a);
332                                                 }
333
334                                                 @Override
335                                                 public T getValue() {
336                                                         return b;
337                                                 }
338
339                                                 @Override
340                                                 public T setValue(T arg0) {
341                                                         throw new UnsupportedOperationException("Not supported");
342                                                 }
343                                                 
344                                         });
345                                         return true;
346                                 }
347                                 
348                         });
349                         return result;
350                 }
351
352                 @Override
353                 public T get(Object resource) {
354                         ResourceImpl impl = (ResourceImpl)resource;
355                         return backend.get(impl.id);
356                 }
357
358                 @Override
359                 public boolean isEmpty() {
360                         return backend.isEmpty();
361                 }
362
363                 public class CallbackEntry<E> implements ResourceMapEntry<E> {
364                         
365                         int id;
366                         E value;
367                         
368                         @Override
369                         public Resource getKey() {
370                                 return new ResourceImpl(session.resourceSupport, id);
371                         }
372
373                         @Override
374                         public E getValue() {
375                                 return value;
376                         }
377                         
378                 }
379                 
380                 @Override
381                 public void iterateEntries(final Callback<ResourceMapEntry<T>> callback) {
382                         final CallbackEntry<T> entry = new CallbackEntry<T>();
383                         backend.forEach(new TIntProcedure() {
384                                 
385                                 @Override
386                                 public boolean execute(int value) {
387                                         entry.id = value;
388                                         entry.value = backend.get(value);
389                                         callback.run(entry);
390                                         return true;
391                                 }
392                         });
393                 }
394                 
395                 @Override
396                 public Set<Resource> keySet() {
397                         final ResourceSet result = new ResourceSet(session);
398                         backend.forEach(new TIntProcedure() {
399                                 
400                                 @Override
401                                 public boolean execute(int value) {
402                                         result.add(value);
403                                         return true;
404                                 }
405                         });
406                         return result;
407                 }
408
409                 @Override
410                 public T put(Resource resource, T value) {
411                         ResourceImpl impl = (ResourceImpl)resource;
412                         return backend.put(impl.id, value);
413                 }
414
415                 @Override
416                 public void putAll(Map<? extends Resource, ? extends T> map) {
417                         @SuppressWarnings("unchecked")
418                         ResourceMap<T> other = (ResourceMap<T>)map;
419                         other.backend.forEachEntry(new TIntObjectProcedure<T>() {
420
421                                 @Override
422                                 public boolean execute(int a, T b) {
423                                         backend.put(a, b);
424                                         return true;
425                                 }
426                                 
427                         });
428                 }
429
430                 @Override
431                 public T remove(Object arg0) {
432                         throw new UnsupportedOperationException("Not implemented");
433                 }
434
435                 @Override
436                 public int size() {
437                         return backend.size();
438                 }
439
440                 @SuppressWarnings("unchecked")
441                 @Override
442                 public Collection<T> values() {
443                         ArrayList<T> result = new ArrayList<T>();
444                         for(Object o : backend.values()) result.add((T)o);
445                         return result;
446                 }
447
448                 @Override
449                 public int hashCode() {
450                         return backend.hashCode();
451                 }
452
453                 @Override
454                 public boolean equals(Object obj) {
455                         if (this == obj)
456                                 return true;
457                         if (obj == null)
458                                 return false;
459                         if (getClass() != obj.getClass())
460                                 return false;
461                         ResourceMap<?> other = (ResourceMap<?>) obj;
462                         return session == other.session && backend.equals(other.backend);
463                 }
464         
465     }
466     
467         @SuppressWarnings("unchecked")
468         @Override
469         public <T, I> T createMap(Class<I> clazz) {
470                 return (T)new ResourceMap<I>(session);
471         }
472
473     static final class ResourceSet implements Set<Resource> {
474         
475         final private SessionImplSocket session;
476         final private TIntHashSet backend;
477
478         ResourceSet(SessionImplSocket session) {
479                 this.session = session;
480                 backend = new TIntHashSet();
481         }
482         
483         ResourceSet(SessionImplSocket session, int capacity) {
484                 this.session = session;
485                 backend = new TIntHashSet(capacity);
486         }
487
488         @Override
489                 public void clear() {
490                         backend.clear();
491                 }
492
493                 @Override
494                 public int size() {
495                         return backend.size();
496                 }
497
498                 @Override
499                 public boolean add(Resource resource) {
500                         ResourceImpl impl = (ResourceImpl)resource;
501                         return backend.add(impl.id);
502                 }
503                 
504                 boolean add(int id) {
505                         return backend.add(id);
506                 }
507
508                 @Override
509                 public boolean addAll(Collection<? extends Resource> rs) {
510                         boolean result = true;
511                         for(Resource r : rs) result &= add(r);
512                         return result;
513                 }
514
515                 @Override
516                 public boolean contains(Object resource) {
517                         ResourceImpl impl = (ResourceImpl)resource;
518                         return backend.contains(impl.id);
519                 }
520
521                 @Override
522                 public boolean containsAll(Collection<?> rs) {
523                         boolean result = true;
524                         for(Object r : rs) result &= contains(r);
525                         return result;
526                 }
527
528                 @Override
529                 public boolean isEmpty() {
530                         return backend.isEmpty();
531                 }
532
533                 @Override
534                 public Iterator<Resource> iterator() {
535                         return new Iterator<Resource>() {
536
537                                 TIntIterator it = backend.iterator();
538                                 
539                                 @Override
540                                 public boolean hasNext() {
541                                         return it.hasNext();
542                                 }
543
544                                 @Override
545                                 public Resource next() {
546                                         return new ResourceImpl(session.resourceSupport, it.next());
547                                 }
548
549                                 @Override
550                                 public void remove() {
551                                         it.remove();
552                                 }
553                                 
554                         };
555                 }
556
557                 @Override
558                 public boolean remove(Object resource) {
559                         ResourceImpl impl = (ResourceImpl)resource;
560                         return backend.remove(impl.id);
561                 }
562
563                 @Override
564                 public boolean removeAll(Collection<?> rs) {
565                         boolean result = true;
566                         for(Object r : rs) result &= remove(r);
567                         return result;
568                 }
569
570                 @Override
571                 public boolean retainAll(Collection<?> arg0) {
572                         throw new UnsupportedOperationException("Not implemented");
573                 }
574
575                 @Override
576                 public Object[] toArray() {
577                         throw new UnsupportedOperationException("Not implemented");
578                 }
579
580                 @SuppressWarnings("unchecked")
581                 @Override
582                 public <T> T[] toArray(T[] arg0) {
583                         final T[] result = (T[])Array.newInstance(arg0.getClass().getComponentType(), backend.size());
584                         backend.forEach(new TIntProcedure() {
585                                 
586                                 int index = 0;
587                                 
588                                 @Override
589                                 public boolean execute(int value) {
590                                         result[index++] = (T)new ResourceImpl(session.resourceSupport, value);
591                                         return true;
592                                 }
593                         });
594                         return result;
595                 }
596
597                 @Override
598                 public int hashCode() {
599                         return backend.hashCode();
600                 }
601
602                 @Override
603                 public boolean equals(Object obj) {
604                         if (this == obj)
605                                 return true;
606                         if (obj == null)
607                                 return false;
608                         if (getClass() != obj.getClass())
609                                 return false;
610                         ResourceSet other = (ResourceSet) obj;
611                         return session == other.session && backend.equals(other.backend);
612                 }
613         
614     }
615         
616         @Override
617         public Set<Resource> createSet() {
618                 return new ResourceSet(session);
619         }
620         
621         @Override
622         public Set<Resource> createSet(int capacity) {
623                 return new ResourceSet(session, capacity);
624         }
625
626         static final class ResourceList implements List<Resource> {
627         
628         final private SessionImplSocket session;
629         final private TIntArrayList backend;
630
631         ResourceList(SessionImplSocket session) {
632                 this.session = session;
633                 this.backend = new TIntArrayList();
634         }
635
636         ResourceList(SessionImplSocket session, Collection<Resource> rs) {
637                 this.session = session;
638                 this.backend = new TIntArrayList(rs.size());
639                 addAll(rs);
640         }
641
642                 @Override
643                 public void clear() {
644                         throw new UnsupportedOperationException("Not implemented");
645                 }
646
647                 @Override
648                 public int size() {
649                         return backend.size();
650                 }
651
652                 @Override
653                 public boolean add(Resource resource) {
654                         if(resource == null) {
655                                 backend.add(0);
656                         } else {
657                                 ResourceImpl impl = (ResourceImpl)resource;
658                                 backend.add(impl.id);
659                         }
660                         return true;
661                 }
662
663                 @Override
664                 public boolean addAll(Collection<? extends Resource> rs) {
665                         if(rs instanceof ResourceList) {
666                                 ResourceList rl = (ResourceList)rs;
667                                 backend.addAll(rl.backend);
668                                 return !rl.isEmpty();
669                         }
670                         boolean result = true;
671                         for(Resource r : rs) result &= add(r);
672                         return result;
673                 }
674
675                 @Override
676                 public boolean contains(Object resource) {
677                         ResourceImpl impl = (ResourceImpl)resource;
678                         return backend.contains(impl.id);
679                 }
680
681                 @Override
682                 public boolean containsAll(Collection<?> rs) {
683                         boolean result = true;
684                         for(Object r : rs) result &= contains(r);
685                         return result;
686                 }
687
688                 @Override
689                 public boolean isEmpty() {
690                         return backend.isEmpty();
691                 }
692
693                 @Override
694                 public Iterator<Resource> iterator() {
695                         return new Iterator<Resource>() {
696                                 
697                                 int index = backend.size();
698                                 
699                                 @Override
700                                 public boolean hasNext() {
701                                         return index > 0; 
702                                 }
703
704                                 @Override
705                                 public Resource next() {
706                                         return new ResourceImpl(session.resourceSupport, backend.getQuick(--index));
707                                 }
708
709                                 @Override
710                                 public void remove() {
711                                         throw new UnsupportedOperationException("Not supported");
712                                 }
713                                 
714                         };
715                 }
716
717                 @Override
718                 public boolean remove(Object resource) {
719                         if(!(resource instanceof ResourceImpl)) return false;
720                         ResourceImpl impl = (ResourceImpl)resource;
721                         return backend.remove(impl.id);
722                 }
723
724                 @Override
725                 public boolean removeAll(Collection<?> rs) {
726                         boolean modified = false;
727                         for(Object o : rs)
728                                 modified |= remove(o);
729                         return modified;
730                 }
731
732                 @Override
733                 public boolean retainAll(Collection<?> arg0) {
734                         throw new UnsupportedOperationException("Not implemented");
735                 }
736
737                 @Override
738                 public Object[] toArray() {
739                         return toArray(new Object[backend.size()]);
740                 }
741
742                 @SuppressWarnings("unchecked")
743                 @Override
744                 public <T> T[] toArray(T[] arg0) {
745                         final T[] result = (T[])Array.newInstance(arg0.getClass().getComponentType(), backend.size());
746                         backend.forEach(new TIntProcedure() {
747                                 
748                                 int index = 0;
749                                 
750                                 @Override
751                                 public boolean execute(int value) {
752                                         result[index++] = (T)new ResourceImpl(session.resourceSupport, value);
753                                         return true;
754                                 }
755                         });
756                         return result;
757                 }
758                 
759                 void sort() {
760                         backend.sort();
761                 }
762
763                 @Override
764                 public boolean addAll(int index, Collection<? extends Resource> rs) {
765                         if(rs.isEmpty()) return false;
766                         int i = index;
767                         for(Resource r : rs) {
768                                 add(i++, r);
769                         }
770                         return true;
771                 }
772
773                 @Override
774                 public Resource get(int index) {
775                         int id = backend.get(index);
776                         if(id == 0) return null;
777                         return new ResourceImpl(session.resourceSupport, id);
778                 }
779
780                 @Override
781                 public Resource set(int index, Resource resource) {
782                         ResourceImpl impl = (ResourceImpl)resource;
783                         int old = backend.set(index, impl.id);
784                         if(old == 0) return null;
785                         return new ResourceImpl(session.resourceSupport, old);
786                 }
787
788                 @Override
789                 public void add(int index, Resource resource) {
790                         ResourceImpl impl = (ResourceImpl)resource;
791                         backend.insert(index, impl.id);
792                 }
793
794                 @Override
795                 public Resource remove(int index) {
796                         int id = backend.removeAt(index);
797                         return new ResourceImpl(session.resourceSupport, id);
798                 }
799
800                 @Override
801                 public int indexOf(Object o) {
802                         if(!(o instanceof ResourceImpl)) return -1;
803                         ResourceImpl impl = (ResourceImpl)o;
804                         return backend.indexOf(impl.id);
805                 }
806
807                 @Override
808                 public int lastIndexOf(Object o) {
809                         if(!(o instanceof ResourceImpl)) return -1;
810                         ResourceImpl impl = (ResourceImpl)o;
811                         return backend.lastIndexOf(impl.id);
812                 }
813
814                 @Override
815                 public ListIterator<Resource> listIterator() {
816                         throw new UnsupportedOperationException("Not implemented");
817                 }
818
819                 @Override
820                 public ListIterator<Resource> listIterator(int index) {
821                         throw new UnsupportedOperationException("Not implemented");
822                 }
823
824                 @Override
825                 public List<Resource> subList(int fromIndex, int toIndex) {
826                         ResourceList result = new ResourceList(session);
827                         for(int i=fromIndex;i<toIndex;i++)
828                                 result.add(get(i));
829                         return result;
830                 }
831
832                 @Override
833                 public int hashCode() {
834                         return backend.hashCode();
835                 }
836
837                 @Override
838                 public boolean equals(Object obj) {
839                         if (this == obj)
840                                 return true;
841                         if (obj == null)
842                                 return false;
843                         if (getClass() != obj.getClass())
844                                 return false;
845                         ResourceList other = (ResourceList) obj;
846                         return session == other.session && backend.equals(other.backend);
847                 }
848
849     }
850
851         @Override
852         public List<Resource> createList() {
853                 return new ResourceList(session);
854         }
855
856     static final class StatementList implements Collection<Statement> {
857         
858         final private SessionImplSocket session;
859         final private TIntArrayList backend = new TIntArrayList();
860
861         StatementList(SessionImplSocket session) {
862                 this.session = session;
863         }
864         
865                 @Override
866                 public void clear() {
867                         throw new UnsupportedOperationException("Not implemented");
868                 }
869
870                 @Override
871                 public int size() {
872                         return backend.size() / 3;
873                 }
874
875                 @Override
876                 public boolean add(Statement stm) {
877                         ResourceImpl s = (ResourceImpl)stm.getSubject();
878                         ResourceImpl p = (ResourceImpl)stm.getPredicate();
879                         ResourceImpl o = (ResourceImpl)stm.getObject();
880                         backend.add(s.id);
881                         backend.add(p.id);
882                         backend.add(o.id);
883                         return true;
884                 }
885
886                 @Override
887                 public boolean addAll(Collection<? extends Statement> rs) {
888                         boolean result = true;
889                         for(Statement r : rs) result &= add(r);
890                         return result;
891                 }
892
893                 @Override
894                 public boolean contains(Object statement) {
895                         throw new UnsupportedOperationException("Not implemented");
896                 }
897
898                 @Override
899                 public boolean containsAll(Collection<?> rs) {
900                         throw new UnsupportedOperationException("Not implemented");
901                 }
902
903                 @Override
904                 public boolean isEmpty() {
905                         return backend.isEmpty();
906                 }
907
908                 @Override
909                 public Iterator<Statement> iterator() {
910                         return new Iterator<Statement>() {
911
912                                 int index = 0;
913                                 int max = backend.size();
914                                 
915                                 @Override
916                                 public boolean hasNext() {
917                                         return index < max; 
918                                 }
919
920                                 @Override
921                                 public Statement next() {
922                                         return new DirectStatementImpl(session.resourceSupport, backend.getQuick(index++), backend.getQuick(index++), backend.getQuick(index++));
923                                 }
924
925                                 @Override
926                                 public void remove() {
927                                         throw new UnsupportedOperationException("Not supported");
928                                 }
929                                 
930                         };
931                 }
932
933                 @Override
934                 public boolean remove(Object resource) {
935                         throw new UnsupportedOperationException("Not implemented");
936                 }
937
938                 @Override
939                 public boolean removeAll(Collection<?> rs) {
940                         throw new UnsupportedOperationException("Not implemented");
941                 }
942
943                 @Override
944                 public boolean retainAll(Collection<?> arg0) {
945                         throw new UnsupportedOperationException("Not implemented");
946                 }
947
948                 @Override
949                 public Object[] toArray() {
950                         throw new UnsupportedOperationException("Not implemented");
951                 }
952
953                 @SuppressWarnings("unchecked")
954                 @Override
955                 public <T> T[] toArray(T[] arg0) {
956                         final T[] result = (T[])Array.newInstance(arg0.getClass().getComponentType(), backend.size());
957                         backend.forEach(new TIntProcedure() {
958                                 
959                                 int index = 0;
960                                 
961                                 @Override
962                                 public boolean execute(int value) {
963                                         result[index++] = (T)new ResourceImpl(session.resourceSupport, value);
964                                         return true;
965                                 }
966                         });
967                         return result;
968                 }
969
970                 @Override
971                 public int hashCode() {
972                         return backend.hashCode();
973                 }
974
975                 @Override
976                 public boolean equals(Object obj) {
977                         if (this == obj)
978                                 return true;
979                         if (obj == null)
980                                 return false;
981                         if (getClass() != obj.getClass())
982                                 return false;
983                         StatementList other = (StatementList) obj;
984                         return session == other.session && backend.equals(other.backend);
985                 }
986         
987     }
988
989         @Override
990         public Collection<Statement> createStatementList() {
991                 return new StatementList(session);
992         }
993
994         private static Comparator<Resource> RESOURCE_COMPARATOR = new Comparator<Resource>() {
995                 @Override
996                 public int compare(Resource o1, Resource o2) {
997                         ResourceImpl r1 = (ResourceImpl)o1;
998                         ResourceImpl r2 = (ResourceImpl)o2;
999                         return compare(r1.id, r2.id);
1000                 }
1001
1002                 private int compare(int x, int y) {
1003                         return (x < y) ? -1 : ((x == y) ? 0 : 1);
1004                 }
1005         };
1006
1007         @Override
1008         public void sort(List<Resource> list) {
1009                 if(list instanceof ResourceList) {
1010                         ((ResourceList) list).sort();
1011                 } else {
1012                         Collections.sort(list, RESOURCE_COMPARATOR);
1013                 }
1014         }
1015         
1016         @Override
1017         public List<Resource> asSortedList(Collection<Resource> rs) {
1018                 ResourceList result = new ResourceList(session, rs);
1019                 result.sort();
1020                 return result;
1021         }
1022         
1023         @Override
1024         public org.simantics.db.ResourceSet getResourceSet(ReadGraph graph, Collection<Resource> resources) {
1025             if(resources instanceof ResourceSet) return (org.simantics.db.ResourceSet)resources;
1026             org.simantics.db.ResourceSet result = new IntSet(((ReadGraphImpl)graph).processor.querySupport);
1027             for(Resource r : resources) result.add(r);
1028             return result;
1029         }
1030
1031     @Override
1032     public org.simantics.db.ResourceSet getResourceSet(ReadGraph graph, Resource ... rs) {
1033         org.simantics.db.ResourceSet result = new IntSet(((ReadGraphImpl)graph).processor.querySupport);
1034         for(Resource r : rs) result.add(r);
1035         return result;
1036     }
1037         
1038 }