1 package fi.vtt.simantics.procore.internal;
\r
3 import java.lang.reflect.Array;
\r
4 import java.util.ArrayList;
\r
5 import java.util.Collection;
\r
6 import java.util.Collections;
\r
7 import java.util.Comparator;
\r
8 import java.util.HashSet;
\r
9 import java.util.Iterator;
\r
10 import java.util.List;
\r
11 import java.util.ListIterator;
\r
12 import java.util.Map;
\r
13 import java.util.Set;
\r
15 import org.simantics.db.ReadGraph;
\r
16 import org.simantics.db.Resource;
\r
17 import org.simantics.db.Statement;
\r
18 import org.simantics.db.exception.ResourceNotFoundException;
\r
19 import org.simantics.db.impl.ResourceImpl;
\r
20 import org.simantics.db.impl.graph.ReadGraphImpl;
\r
21 import org.simantics.db.impl.query.IntSet;
\r
22 import org.simantics.db.service.CollectionSupport;
\r
23 import org.simantics.utils.datastructures.Callback;
\r
25 import gnu.trove.impl.Constants;
\r
26 import gnu.trove.iterator.TIntIterator;
\r
27 import gnu.trove.list.array.TIntArrayList;
\r
28 import gnu.trove.map.hash.TIntIntHashMap;
\r
29 import gnu.trove.map.hash.TIntObjectHashMap;
\r
30 import gnu.trove.map.hash.TObjectIntHashMap;
\r
31 import gnu.trove.procedure.TIntObjectProcedure;
\r
32 import gnu.trove.procedure.TIntProcedure;
\r
33 import gnu.trove.procedure.TObjectIntProcedure;
\r
34 import gnu.trove.procedure.TObjectProcedure;
\r
35 import gnu.trove.set.hash.TIntHashSet;
\r
37 public class CollectionSupportImpl implements CollectionSupport {
\r
39 final private SessionImplSocket session;
\r
41 CollectionSupportImpl(SessionImplSocket session) {
\r
42 this.session = session;
\r
45 static final class IntResourceMap {
\r
47 final private SessionImplSocket session;
\r
48 final private TIntIntHashMap backend = new TIntIntHashMap(Constants.DEFAULT_CAPACITY, Constants.DEFAULT_LOAD_FACTOR, -1, 0);
\r
50 IntResourceMap(SessionImplSocket session) {
\r
51 this.session = session;
\r
55 return backend.size();
\r
58 public boolean isEmpty() {
\r
59 return backend.isEmpty();
\r
62 public boolean containsKey(int key) {
\r
63 return backend.containsKey(key);
\r
66 public boolean containsValue(int value) {
\r
67 return backend.containsValue(value);
\r
70 public Resource get(int key) {
\r
72 return session.getResourceByKey(backend.get(key));
\r
73 } catch (ResourceNotFoundException e) {
\r
74 e.printStackTrace();
\r
79 public Resource put(int key, Resource value) {
\r
80 ResourceImpl impl = (ResourceImpl) value;
\r
81 int i = backend.put(key, impl.id);
\r
86 return session.getResourceByKey(i);
\r
87 } catch (ResourceNotFoundException e) {
\r
88 e.printStackTrace();
\r
93 public Resource remove(int key) {
\r
94 throw new UnsupportedOperationException("remove not supported");
\r
98 public int hashCode() {
\r
99 return backend.hashCode();
\r
103 public boolean equals(Object obj) {
\r
108 if (getClass() != obj.getClass())
\r
110 IntResourceMap other = (IntResourceMap) obj;
\r
111 return session == other.session && backend.equals(other.backend);
\r
115 public IntResourceMap createIntResourceMap() {
\r
116 return new IntResourceMap(session);
\r
119 static final class ObjectResourceMap<T> implements Map<T, Resource> {
\r
121 final private SessionImplSocket session;
\r
122 final private TObjectIntHashMap<T> backend;
\r
124 ObjectResourceMap(SessionImplSocket session) {
\r
125 this.session = session;
\r
126 backend = new TObjectIntHashMap<T>(Constants.DEFAULT_CAPACITY, Constants.DEFAULT_LOAD_FACTOR, 0);
\r
129 ObjectResourceMap(SessionImplSocket session, int capacity) {
\r
130 this.session = session;
\r
131 backend = new TObjectIntHashMap<T>(capacity, Constants.DEFAULT_LOAD_FACTOR, 0);
\r
135 public int size() {
\r
136 return backend.size();
\r
139 public boolean isEmpty() {
\r
140 return backend.isEmpty();
\r
144 public boolean containsKey(Object key) {
\r
145 return backend.contains(key);
\r
149 public boolean containsValue(Object value) {
\r
150 ResourceImpl impl = (ResourceImpl) value;
\r
151 return backend.containsValue(impl.id);
\r
155 public Resource get(Object key) {
\r
157 int result = backend.get(key);
\r
160 return session.getResourceByKey(result);
\r
161 } catch (ResourceNotFoundException e) {
\r
162 e.printStackTrace();
\r
168 public Resource put(T key, Resource value) {
\r
169 ResourceImpl impl = (ResourceImpl) value;
\r
170 int i = backend.put(key, impl.id);
\r
175 return session.getResourceByKey(i);
\r
176 } catch (ResourceNotFoundException e) {
\r
177 e.printStackTrace();
\r
183 public Resource remove(Object key) {
\r
184 throw new UnsupportedOperationException("remove not supported, structure is immutable");
\r
188 public void putAll(Map<? extends T, ? extends Resource> map) {
\r
189 @SuppressWarnings("unchecked")
\r
190 ObjectResourceMap<T> other = (ObjectResourceMap<T>) map;
\r
191 other.backend.forEachEntry(new TObjectIntProcedure<T>() {
\r
194 public boolean execute(T a, int b) {
\r
202 public void clear() {
\r
203 throw new UnsupportedOperationException("clear not supported, structure is immutable");
\r
207 public Set<T> keySet() {
\r
208 final Set<T> result = new HashSet<T>();
\r
209 backend.forEach(new TObjectProcedure<T>() {
\r
212 public boolean execute(T object) {
\r
213 result.add(object);
\r
221 public Collection<Resource> values() {
\r
222 ArrayList<Resource> result = new ArrayList<Resource>();
\r
223 for (int key : backend.values()) {
\r
225 result.add(session.getResourceByKey(key));
\r
226 } catch (ResourceNotFoundException e) {
\r
227 e.printStackTrace();
\r
234 public Set<java.util.Map.Entry<T, Resource>> entrySet() {
\r
235 final HashSet<java.util.Map.Entry<T, Resource>> result = new HashSet<java.util.Map.Entry<T, Resource>>();
\r
236 backend.forEachEntry(new TObjectIntProcedure<T>() {
\r
239 public boolean execute(final T a, final int b) {
\r
240 return result.add(new Map.Entry<T, Resource>() {
\r
243 public T getKey() {
\r
248 public Resource getValue() {
\r
249 return new ResourceImpl(session.resourceSupport, b);
\r
253 public Resource setValue(Resource value) {
\r
254 throw new UnsupportedOperationException("Map.Entry.setValue not supported, structure is immutable");
\r
264 public int hashCode() {
\r
265 return backend.hashCode();
\r
269 public boolean equals(Object obj) {
\r
274 if (getClass() != obj.getClass())
\r
276 ObjectResourceMap<?> other = (ObjectResourceMap<?>) obj;
\r
277 return session == other.session && backend.equals(other.backend);
\r
282 @SuppressWarnings("unchecked")
\r
284 public <T, I> T createObjectResourceMap(Class<I> clazz) {
\r
285 return (T)new ObjectResourceMap<I>(session);
\r
288 @SuppressWarnings("unchecked")
\r
290 public <T, I> T createObjectResourceMap(Class<I> clazz, int capacity) {
\r
291 return (T)new ObjectResourceMap<I>(session, capacity);
\r
294 static final class ResourceMap<T> implements org.simantics.db.ResourceMap<T> {
\r
296 final private SessionImplSocket session;
\r
297 final private TIntObjectHashMap<T> backend = new TIntObjectHashMap<T>();
\r
299 ResourceMap(SessionImplSocket session) {
\r
300 this.session = session;
\r
304 public void clear() {
\r
305 throw new UnsupportedOperationException("Not implemented");
\r
309 public boolean containsKey(Object resource) {
\r
310 ResourceImpl impl = (ResourceImpl)resource;
\r
311 return backend.containsKey(impl.id);
\r
314 @SuppressWarnings("unchecked")
\r
316 public boolean containsValue(Object value) {
\r
317 return backend.containsValue((T)value);
\r
321 public Set<java.util.Map.Entry<Resource, T>> entrySet() {
\r
322 final HashSet<java.util.Map.Entry<Resource, T>> result = new HashSet<java.util.Map.Entry<Resource, T>>();
\r
323 backend.forEachEntry(new TIntObjectProcedure<T>() {
\r
326 public boolean execute(final int a, final T b) {
\r
327 result.add(new Map.Entry<Resource, T>() {
\r
330 public Resource getKey() {
\r
331 return new ResourceImpl(session.resourceSupport, a);
\r
335 public T getValue() {
\r
340 public T setValue(T arg0) {
\r
341 throw new UnsupportedOperationException("Not supported");
\r
353 public T get(Object resource) {
\r
354 ResourceImpl impl = (ResourceImpl)resource;
\r
355 return backend.get(impl.id);
\r
359 public boolean isEmpty() {
\r
360 return backend.isEmpty();
\r
363 public class CallbackEntry<E> implements ResourceMapEntry<E> {
\r
369 public Resource getKey() {
\r
370 return new ResourceImpl(session.resourceSupport, id);
\r
374 public E getValue() {
\r
381 public void iterateEntries(final Callback<ResourceMapEntry<T>> callback) {
\r
382 final CallbackEntry<T> entry = new CallbackEntry<T>();
\r
383 backend.forEach(new TIntProcedure() {
\r
386 public boolean execute(int value) {
\r
388 entry.value = backend.get(value);
\r
389 callback.run(entry);
\r
396 public Set<Resource> keySet() {
\r
397 final ResourceSet result = new ResourceSet(session);
\r
398 backend.forEach(new TIntProcedure() {
\r
401 public boolean execute(int value) {
\r
410 public T put(Resource resource, T value) {
\r
411 ResourceImpl impl = (ResourceImpl)resource;
\r
412 return backend.put(impl.id, value);
\r
416 public void putAll(Map<? extends Resource, ? extends T> map) {
\r
417 @SuppressWarnings("unchecked")
\r
418 ResourceMap<T> other = (ResourceMap<T>)map;
\r
419 other.backend.forEachEntry(new TIntObjectProcedure<T>() {
\r
422 public boolean execute(int a, T b) {
\r
431 public T remove(Object arg0) {
\r
432 throw new UnsupportedOperationException("Not implemented");
\r
436 public int size() {
\r
437 return backend.size();
\r
440 @SuppressWarnings("unchecked")
\r
442 public Collection<T> values() {
\r
443 ArrayList<T> result = new ArrayList<T>();
\r
444 for(Object o : backend.values()) result.add((T)o);
\r
449 public int hashCode() {
\r
450 return backend.hashCode();
\r
454 public boolean equals(Object obj) {
\r
459 if (getClass() != obj.getClass())
\r
461 ResourceMap<?> other = (ResourceMap<?>) obj;
\r
462 return session == other.session && backend.equals(other.backend);
\r
467 @SuppressWarnings("unchecked")
\r
469 public <T, I> T createMap(Class<I> clazz) {
\r
470 return (T)new ResourceMap<I>(session);
\r
473 static final class ResourceSet implements Set<Resource> {
\r
475 final private SessionImplSocket session;
\r
476 final private TIntHashSet backend;
\r
478 ResourceSet(SessionImplSocket session) {
\r
479 this.session = session;
\r
480 backend = new TIntHashSet();
\r
483 ResourceSet(SessionImplSocket session, int capacity) {
\r
484 this.session = session;
\r
485 backend = new TIntHashSet(capacity);
\r
489 public void clear() {
\r
494 public int size() {
\r
495 return backend.size();
\r
499 public boolean add(Resource resource) {
\r
500 ResourceImpl impl = (ResourceImpl)resource;
\r
501 return backend.add(impl.id);
\r
504 boolean add(int id) {
\r
505 return backend.add(id);
\r
509 public boolean addAll(Collection<? extends Resource> rs) {
\r
510 boolean result = true;
\r
511 for(Resource r : rs) result &= add(r);
\r
516 public boolean contains(Object resource) {
\r
517 ResourceImpl impl = (ResourceImpl)resource;
\r
518 return backend.contains(impl.id);
\r
522 public boolean containsAll(Collection<?> rs) {
\r
523 boolean result = true;
\r
524 for(Object r : rs) result &= contains(r);
\r
529 public boolean isEmpty() {
\r
530 return backend.isEmpty();
\r
534 public Iterator<Resource> iterator() {
\r
535 return new Iterator<Resource>() {
\r
537 TIntIterator it = backend.iterator();
\r
540 public boolean hasNext() {
\r
541 return it.hasNext();
\r
545 public Resource next() {
\r
546 return new ResourceImpl(session.resourceSupport, it.next());
\r
550 public void remove() {
\r
558 public boolean remove(Object resource) {
\r
559 ResourceImpl impl = (ResourceImpl)resource;
\r
560 return backend.remove(impl.id);
\r
564 public boolean removeAll(Collection<?> rs) {
\r
565 boolean result = true;
\r
566 for(Object r : rs) result &= remove(r);
\r
571 public boolean retainAll(Collection<?> arg0) {
\r
572 throw new UnsupportedOperationException("Not implemented");
\r
576 public Object[] toArray() {
\r
577 throw new UnsupportedOperationException("Not implemented");
\r
580 @SuppressWarnings("unchecked")
\r
582 public <T> T[] toArray(T[] arg0) {
\r
583 final T[] result = (T[])Array.newInstance(arg0.getClass().getComponentType(), backend.size());
\r
584 backend.forEach(new TIntProcedure() {
\r
589 public boolean execute(int value) {
\r
590 result[index++] = (T)new ResourceImpl(session.resourceSupport, value);
\r
598 public int hashCode() {
\r
599 return backend.hashCode();
\r
603 public boolean equals(Object obj) {
\r
608 if (getClass() != obj.getClass())
\r
610 ResourceSet other = (ResourceSet) obj;
\r
611 return session == other.session && backend.equals(other.backend);
\r
617 public Set<Resource> createSet() {
\r
618 return new ResourceSet(session);
\r
622 public Set<Resource> createSet(int capacity) {
\r
623 return new ResourceSet(session, capacity);
\r
626 static final class ResourceList implements List<Resource> {
\r
628 final private SessionImplSocket session;
\r
629 final private TIntArrayList backend;
\r
631 ResourceList(SessionImplSocket session) {
\r
632 this.session = session;
\r
633 this.backend = new TIntArrayList();
\r
636 ResourceList(SessionImplSocket session, Collection<Resource> rs) {
\r
637 this.session = session;
\r
638 this.backend = new TIntArrayList(rs.size());
\r
643 public void clear() {
\r
644 throw new UnsupportedOperationException("Not implemented");
\r
648 public int size() {
\r
649 return backend.size();
\r
653 public boolean add(Resource resource) {
\r
654 if(resource == null) {
\r
657 ResourceImpl impl = (ResourceImpl)resource;
\r
658 backend.add(impl.id);
\r
664 public boolean addAll(Collection<? extends Resource> rs) {
\r
665 if(rs instanceof ResourceList) {
\r
666 ResourceList rl = (ResourceList)rs;
\r
667 backend.addAll(rl.backend);
\r
668 return !rl.isEmpty();
\r
670 boolean result = true;
\r
671 for(Resource r : rs) result &= add(r);
\r
676 public boolean contains(Object resource) {
\r
677 ResourceImpl impl = (ResourceImpl)resource;
\r
678 return backend.contains(impl.id);
\r
682 public boolean containsAll(Collection<?> rs) {
\r
683 boolean result = true;
\r
684 for(Object r : rs) result &= contains(r);
\r
689 public boolean isEmpty() {
\r
690 return backend.isEmpty();
\r
694 public Iterator<Resource> iterator() {
\r
695 return new Iterator<Resource>() {
\r
697 int index = backend.size();
\r
700 public boolean hasNext() {
\r
705 public Resource next() {
\r
706 return new ResourceImpl(session.resourceSupport, backend.getQuick(--index));
\r
710 public void remove() {
\r
711 throw new UnsupportedOperationException("Not supported");
\r
718 public boolean remove(Object resource) {
\r
719 if(!(resource instanceof ResourceImpl)) return false;
\r
720 ResourceImpl impl = (ResourceImpl)resource;
\r
721 return backend.remove(impl.id);
\r
725 public boolean removeAll(Collection<?> rs) {
\r
726 boolean modified = false;
\r
728 modified |= remove(o);
\r
733 public boolean retainAll(Collection<?> arg0) {
\r
734 throw new UnsupportedOperationException("Not implemented");
\r
738 public Object[] toArray() {
\r
739 return toArray(new Object[backend.size()]);
\r
742 @SuppressWarnings("unchecked")
\r
744 public <T> T[] toArray(T[] arg0) {
\r
745 final T[] result = (T[])Array.newInstance(arg0.getClass().getComponentType(), backend.size());
\r
746 backend.forEach(new TIntProcedure() {
\r
751 public boolean execute(int value) {
\r
752 result[index++] = (T)new ResourceImpl(session.resourceSupport, value);
\r
764 public boolean addAll(int index, Collection<? extends Resource> rs) {
\r
765 if(rs.isEmpty()) return false;
\r
767 for(Resource r : rs) {
\r
774 public Resource get(int index) {
\r
775 int id = backend.get(index);
\r
776 if(id == 0) return null;
\r
777 return new ResourceImpl(session.resourceSupport, id);
\r
781 public Resource set(int index, Resource resource) {
\r
782 ResourceImpl impl = (ResourceImpl)resource;
\r
783 int old = backend.set(index, impl.id);
\r
784 if(old == 0) return null;
\r
785 return new ResourceImpl(session.resourceSupport, old);
\r
789 public void add(int index, Resource resource) {
\r
790 ResourceImpl impl = (ResourceImpl)resource;
\r
791 backend.insert(index, impl.id);
\r
795 public Resource remove(int index) {
\r
796 int id = backend.removeAt(index);
\r
797 return new ResourceImpl(session.resourceSupport, id);
\r
801 public int indexOf(Object o) {
\r
802 if(!(o instanceof ResourceImpl)) return -1;
\r
803 ResourceImpl impl = (ResourceImpl)o;
\r
804 return backend.indexOf(impl.id);
\r
808 public int lastIndexOf(Object o) {
\r
809 if(!(o instanceof ResourceImpl)) return -1;
\r
810 ResourceImpl impl = (ResourceImpl)o;
\r
811 return backend.lastIndexOf(impl.id);
\r
815 public ListIterator<Resource> listIterator() {
\r
816 throw new UnsupportedOperationException("Not implemented");
\r
820 public ListIterator<Resource> listIterator(int index) {
\r
821 throw new UnsupportedOperationException("Not implemented");
\r
825 public List<Resource> subList(int fromIndex, int toIndex) {
\r
826 ResourceList result = new ResourceList(session);
\r
827 for(int i=fromIndex;i<toIndex;i++)
\r
828 result.add(get(i));
\r
833 public int hashCode() {
\r
834 return backend.hashCode();
\r
838 public boolean equals(Object obj) {
\r
843 if (getClass() != obj.getClass())
\r
845 ResourceList other = (ResourceList) obj;
\r
846 return session == other.session && backend.equals(other.backend);
\r
852 public List<Resource> createList() {
\r
853 return new ResourceList(session);
\r
856 static final class StatementList implements Collection<Statement> {
\r
858 final private SessionImplSocket session;
\r
859 final private TIntArrayList backend = new TIntArrayList();
\r
861 StatementList(SessionImplSocket session) {
\r
862 this.session = session;
\r
866 public void clear() {
\r
867 throw new UnsupportedOperationException("Not implemented");
\r
871 public int size() {
\r
872 return backend.size() / 3;
\r
876 public boolean add(Statement stm) {
\r
877 ResourceImpl s = (ResourceImpl)stm.getSubject();
\r
878 ResourceImpl p = (ResourceImpl)stm.getPredicate();
\r
879 ResourceImpl o = (ResourceImpl)stm.getObject();
\r
887 public boolean addAll(Collection<? extends Statement> rs) {
\r
888 boolean result = true;
\r
889 for(Statement r : rs) result &= add(r);
\r
894 public boolean contains(Object statement) {
\r
895 throw new UnsupportedOperationException("Not implemented");
\r
899 public boolean containsAll(Collection<?> rs) {
\r
900 throw new UnsupportedOperationException("Not implemented");
\r
904 public boolean isEmpty() {
\r
905 return backend.isEmpty();
\r
909 public Iterator<Statement> iterator() {
\r
910 return new Iterator<Statement>() {
\r
913 int max = backend.size();
\r
916 public boolean hasNext() {
\r
917 return index < max;
\r
921 public Statement next() {
\r
922 return new DirectStatementImpl(session.resourceSupport, backend.getQuick(index++), backend.getQuick(index++), backend.getQuick(index++));
\r
926 public void remove() {
\r
927 throw new UnsupportedOperationException("Not supported");
\r
934 public boolean remove(Object resource) {
\r
935 throw new UnsupportedOperationException("Not implemented");
\r
939 public boolean removeAll(Collection<?> rs) {
\r
940 throw new UnsupportedOperationException("Not implemented");
\r
944 public boolean retainAll(Collection<?> arg0) {
\r
945 throw new UnsupportedOperationException("Not implemented");
\r
949 public Object[] toArray() {
\r
950 throw new UnsupportedOperationException("Not implemented");
\r
953 @SuppressWarnings("unchecked")
\r
955 public <T> T[] toArray(T[] arg0) {
\r
956 final T[] result = (T[])Array.newInstance(arg0.getClass().getComponentType(), backend.size());
\r
957 backend.forEach(new TIntProcedure() {
\r
962 public boolean execute(int value) {
\r
963 result[index++] = (T)new ResourceImpl(session.resourceSupport, value);
\r
971 public int hashCode() {
\r
972 return backend.hashCode();
\r
976 public boolean equals(Object obj) {
\r
981 if (getClass() != obj.getClass())
\r
983 StatementList other = (StatementList) obj;
\r
984 return session == other.session && backend.equals(other.backend);
\r
990 public Collection<Statement> createStatementList() {
\r
991 return new StatementList(session);
\r
994 private static Comparator<Resource> RESOURCE_COMPARATOR = new Comparator<Resource>() {
\r
996 public int compare(Resource o1, Resource o2) {
\r
997 ResourceImpl r1 = (ResourceImpl)o1;
\r
998 ResourceImpl r2 = (ResourceImpl)o2;
\r
999 return compare(r1.id, r2.id);
\r
1002 private int compare(int x, int y) {
\r
1003 return (x < y) ? -1 : ((x == y) ? 0 : 1);
\r
1008 public void sort(List<Resource> list) {
\r
1009 if(list instanceof ResourceList) {
\r
1010 ((ResourceList) list).sort();
\r
1012 Collections.sort(list, RESOURCE_COMPARATOR);
\r
1017 public List<Resource> asSortedList(Collection<Resource> rs) {
\r
1018 ResourceList result = new ResourceList(session, rs);
\r
1024 public org.simantics.db.ResourceSet getResourceSet(ReadGraph graph, Collection<Resource> resources) {
\r
1025 if(resources instanceof ResourceSet) return (org.simantics.db.ResourceSet)resources;
\r
1026 org.simantics.db.ResourceSet result = new IntSet(((ReadGraphImpl)graph).processor.querySupport);
\r
1027 for(Resource r : resources) result.add(r);
\r
1032 public org.simantics.db.ResourceSet getResourceSet(ReadGraph graph, Resource ... rs) {
\r
1033 org.simantics.db.ResourceSet result = new IntSet(((ReadGraphImpl)graph).processor.querySupport);
\r
1034 for(Resource r : rs) result.add(r);
\r