]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/CollectionSupportImpl.java
Cluster loading problem fix made by Antti
[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, int capacity) {
637                 this.session = session;
638                 this.backend = new TIntArrayList(capacity);
639         }
640
641         ResourceList(SessionImplSocket session, Collection<Resource> rs) {
642                 this.session = session;
643                 this.backend = new TIntArrayList(rs.size());
644                 addAll(rs);
645         }
646
647                 @Override
648                 public void clear() {
649                         throw new UnsupportedOperationException("Not implemented");
650                 }
651
652                 @Override
653                 public int size() {
654                         return backend.size();
655                 }
656
657                 @Override
658                 public boolean add(Resource resource) {
659                         if(resource == null) {
660                                 backend.add(0);
661                         } else {
662                                 ResourceImpl impl = (ResourceImpl)resource;
663                                 backend.add(impl.id);
664                         }
665                         return true;
666                 }
667
668                 @Override
669                 public boolean addAll(Collection<? extends Resource> rs) {
670                         if(rs instanceof ResourceList) {
671                                 ResourceList rl = (ResourceList)rs;
672                                 backend.addAll(rl.backend);
673                                 return !rl.isEmpty();
674                         }
675                         boolean result = true;
676                         for(Resource r : rs) result &= add(r);
677                         return result;
678                 }
679
680                 @Override
681                 public boolean contains(Object resource) {
682                         ResourceImpl impl = (ResourceImpl)resource;
683                         return backend.contains(impl.id);
684                 }
685
686                 @Override
687                 public boolean containsAll(Collection<?> rs) {
688                         boolean result = true;
689                         for(Object r : rs) result &= contains(r);
690                         return result;
691                 }
692
693                 @Override
694                 public boolean isEmpty() {
695                         return backend.isEmpty();
696                 }
697
698                 @Override
699                 public Iterator<Resource> iterator() {
700                         return new Iterator<Resource>() {
701                                 
702                                 int index = backend.size();
703                                 
704                                 @Override
705                                 public boolean hasNext() {
706                                         return index > 0; 
707                                 }
708
709                                 @Override
710                                 public Resource next() {
711                                         return new ResourceImpl(session.resourceSupport, backend.getQuick(--index));
712                                 }
713
714                                 @Override
715                                 public void remove() {
716                                         throw new UnsupportedOperationException("Not supported");
717                                 }
718                                 
719                         };
720                 }
721
722                 @Override
723                 public boolean remove(Object resource) {
724                         if(!(resource instanceof ResourceImpl)) return false;
725                         ResourceImpl impl = (ResourceImpl)resource;
726                         return backend.remove(impl.id);
727                 }
728
729                 @Override
730                 public boolean removeAll(Collection<?> rs) {
731                         boolean modified = false;
732                         for(Object o : rs)
733                                 modified |= remove(o);
734                         return modified;
735                 }
736
737                 @Override
738                 public boolean retainAll(Collection<?> arg0) {
739                         throw new UnsupportedOperationException("Not implemented");
740                 }
741
742                 @Override
743                 public Object[] toArray() {
744                         return toArray(new Object[backend.size()]);
745                 }
746
747                 @SuppressWarnings("unchecked")
748                 @Override
749                 public <T> T[] toArray(T[] arg0) {
750                         final T[] result = (T[])Array.newInstance(arg0.getClass().getComponentType(), backend.size());
751                         backend.forEach(new TIntProcedure() {
752                                 
753                                 int index = 0;
754                                 
755                                 @Override
756                                 public boolean execute(int value) {
757                                         result[index++] = (T)new ResourceImpl(session.resourceSupport, value);
758                                         return true;
759                                 }
760                         });
761                         return result;
762                 }
763                 
764                 void sort() {
765                         backend.sort();
766                 }
767
768                 @Override
769                 public boolean addAll(int index, Collection<? extends Resource> rs) {
770                         if(rs.isEmpty()) return false;
771                         int i = index;
772                         for(Resource r : rs) {
773                                 add(i++, r);
774                         }
775                         return true;
776                 }
777
778                 @Override
779                 public Resource get(int index) {
780                         int id = backend.get(index);
781                         if(id == 0) return null;
782                         return new ResourceImpl(session.resourceSupport, id);
783                 }
784
785                 @Override
786                 public Resource set(int index, Resource resource) {
787                         ResourceImpl impl = (ResourceImpl)resource;
788                         int old = backend.set(index, impl.id);
789                         if(old == 0) return null;
790                         return new ResourceImpl(session.resourceSupport, old);
791                 }
792
793                 @Override
794                 public void add(int index, Resource resource) {
795                         ResourceImpl impl = (ResourceImpl)resource;
796                         backend.insert(index, impl.id);
797                 }
798
799                 @Override
800                 public Resource remove(int index) {
801                         int id = backend.removeAt(index);
802                         return new ResourceImpl(session.resourceSupport, id);
803                 }
804
805                 @Override
806                 public int indexOf(Object o) {
807                         if(!(o instanceof ResourceImpl)) return -1;
808                         ResourceImpl impl = (ResourceImpl)o;
809                         return backend.indexOf(impl.id);
810                 }
811
812                 @Override
813                 public int lastIndexOf(Object o) {
814                         if(!(o instanceof ResourceImpl)) return -1;
815                         ResourceImpl impl = (ResourceImpl)o;
816                         return backend.lastIndexOf(impl.id);
817                 }
818
819                 @Override
820                 public ListIterator<Resource> listIterator() {
821                         throw new UnsupportedOperationException("Not implemented");
822                 }
823
824                 @Override
825                 public ListIterator<Resource> listIterator(int index) {
826                         throw new UnsupportedOperationException("Not implemented");
827                 }
828
829                 @Override
830                 public List<Resource> subList(int fromIndex, int toIndex) {
831                         ResourceList result = new ResourceList(session);
832                         for(int i=fromIndex;i<toIndex;i++)
833                                 result.add(get(i));
834                         return result;
835                 }
836
837                 @Override
838                 public int hashCode() {
839                         return backend.hashCode();
840                 }
841
842                 @Override
843                 public boolean equals(Object obj) {
844                         if (this == obj)
845                                 return true;
846                         if (obj == null)
847                                 return false;
848                         if (getClass() != obj.getClass())
849                                 return false;
850                         ResourceList other = (ResourceList) obj;
851                         return session == other.session && backend.equals(other.backend);
852                 }
853
854     }
855
856         @Override
857         public List<Resource> createList() {
858                 return new ResourceList(session);
859         }
860
861         @Override
862         public List<Resource> createList(int capacity) {
863                 return new ResourceList(session, capacity);
864         }
865
866     static final class StatementList implements Collection<Statement> {
867         
868         final private SessionImplSocket session;
869         final private TIntArrayList backend = new TIntArrayList();
870
871         StatementList(SessionImplSocket session) {
872                 this.session = session;
873         }
874         
875                 @Override
876                 public void clear() {
877                         throw new UnsupportedOperationException("Not implemented");
878                 }
879
880                 @Override
881                 public int size() {
882                         return backend.size() / 3;
883                 }
884
885                 @Override
886                 public boolean add(Statement stm) {
887                         ResourceImpl s = (ResourceImpl)stm.getSubject();
888                         ResourceImpl p = (ResourceImpl)stm.getPredicate();
889                         ResourceImpl o = (ResourceImpl)stm.getObject();
890                         backend.add(s.id);
891                         backend.add(p.id);
892                         backend.add(o.id);
893                         return true;
894                 }
895
896                 @Override
897                 public boolean addAll(Collection<? extends Statement> rs) {
898                         boolean result = true;
899                         for(Statement r : rs) result &= add(r);
900                         return result;
901                 }
902
903                 @Override
904                 public boolean contains(Object statement) {
905                         throw new UnsupportedOperationException("Not implemented");
906                 }
907
908                 @Override
909                 public boolean containsAll(Collection<?> rs) {
910                         throw new UnsupportedOperationException("Not implemented");
911                 }
912
913                 @Override
914                 public boolean isEmpty() {
915                         return backend.isEmpty();
916                 }
917
918                 @Override
919                 public Iterator<Statement> iterator() {
920                         return new Iterator<Statement>() {
921
922                                 int index = 0;
923                                 int max = backend.size();
924                                 
925                                 @Override
926                                 public boolean hasNext() {
927                                         return index < max; 
928                                 }
929
930                                 @Override
931                                 public Statement next() {
932                                         return new DirectStatementImpl(session.resourceSupport, backend.getQuick(index++), backend.getQuick(index++), backend.getQuick(index++));
933                                 }
934
935                                 @Override
936                                 public void remove() {
937                                         throw new UnsupportedOperationException("Not supported");
938                                 }
939                                 
940                         };
941                 }
942
943                 @Override
944                 public boolean remove(Object resource) {
945                         throw new UnsupportedOperationException("Not implemented");
946                 }
947
948                 @Override
949                 public boolean removeAll(Collection<?> rs) {
950                         throw new UnsupportedOperationException("Not implemented");
951                 }
952
953                 @Override
954                 public boolean retainAll(Collection<?> arg0) {
955                         throw new UnsupportedOperationException("Not implemented");
956                 }
957
958                 @Override
959                 public Object[] toArray() {
960                         throw new UnsupportedOperationException("Not implemented");
961                 }
962
963                 @SuppressWarnings("unchecked")
964                 @Override
965                 public <T> T[] toArray(T[] arg0) {
966                         final T[] result = (T[])Array.newInstance(arg0.getClass().getComponentType(), backend.size());
967                         backend.forEach(new TIntProcedure() {
968                                 
969                                 int index = 0;
970                                 
971                                 @Override
972                                 public boolean execute(int value) {
973                                         result[index++] = (T)new ResourceImpl(session.resourceSupport, value);
974                                         return true;
975                                 }
976                         });
977                         return result;
978                 }
979
980                 @Override
981                 public int hashCode() {
982                         return backend.hashCode();
983                 }
984
985                 @Override
986                 public boolean equals(Object obj) {
987                         if (this == obj)
988                                 return true;
989                         if (obj == null)
990                                 return false;
991                         if (getClass() != obj.getClass())
992                                 return false;
993                         StatementList other = (StatementList) obj;
994                         return session == other.session && backend.equals(other.backend);
995                 }
996         
997     }
998
999         @Override
1000         public Collection<Statement> createStatementList() {
1001                 return new StatementList(session);
1002         }
1003
1004         private static Comparator<Resource> RESOURCE_COMPARATOR = new Comparator<Resource>() {
1005                 @Override
1006                 public int compare(Resource o1, Resource o2) {
1007                         ResourceImpl r1 = (ResourceImpl)o1;
1008                         ResourceImpl r2 = (ResourceImpl)o2;
1009                         return compare(r1.id, r2.id);
1010                 }
1011
1012                 private int compare(int x, int y) {
1013                         return (x < y) ? -1 : ((x == y) ? 0 : 1);
1014                 }
1015         };
1016
1017         @Override
1018         public void sort(List<Resource> list) {
1019                 if(list instanceof ResourceList) {
1020                         ((ResourceList) list).sort();
1021                 } else {
1022                         Collections.sort(list, RESOURCE_COMPARATOR);
1023                 }
1024         }
1025         
1026         @Override
1027         public List<Resource> asSortedList(Collection<Resource> rs) {
1028                 ResourceList result = new ResourceList(session, rs);
1029                 result.sort();
1030                 return result;
1031         }
1032         
1033         @Override
1034         public org.simantics.db.ResourceSet getResourceSet(ReadGraph graph, Collection<Resource> resources) {
1035             if(resources instanceof ResourceSet) return (org.simantics.db.ResourceSet)resources;
1036             org.simantics.db.ResourceSet result = new IntSet(((ReadGraphImpl)graph).processor.querySupport);
1037             for(Resource r : resources) result.add(r);
1038             return result;
1039         }
1040
1041     @Override
1042     public org.simantics.db.ResourceSet getResourceSet(ReadGraph graph, Resource ... rs) {
1043         org.simantics.db.ResourceSet result = new IntSet(((ReadGraphImpl)graph).processor.querySupport);
1044         for(Resource r : rs) result.add(r);
1045         return result;
1046     }
1047         
1048 }