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