X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.db.procore%2Fsrc%2Ffi%2Fvtt%2Fsimantics%2Fprocore%2Finternal%2FObjectResourceMap.java;fp=bundles%2Forg.simantics.db.procore%2Fsrc%2Ffi%2Fvtt%2Fsimantics%2Fprocore%2Finternal%2FObjectResourceMap.java;h=8b26442d87ff6c70a6e37e4a8dfa980d9f342e2b;hp=0000000000000000000000000000000000000000;hb=0d9b90834ce56b292c00b1a39850ed842c3e4d42;hpb=e5db6157fd8722c946613d4e46d7aaf6bfa92609 diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ObjectResourceMap.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ObjectResourceMap.java new file mode 100644 index 000000000..8b26442d8 --- /dev/null +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ObjectResourceMap.java @@ -0,0 +1,218 @@ +package fi.vtt.simantics.procore.internal; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import org.simantics.db.ObjectResourceIdMap; +import org.simantics.db.Resource; +import org.simantics.db.exception.ResourceNotFoundException; +import org.simantics.db.impl.ResourceImpl; + +import gnu.trove.impl.Constants; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.procedure.TObjectIntProcedure; +import gnu.trove.procedure.TObjectProcedure; + +final class ObjectResourceMap implements Map, ObjectResourceIdMap { + + private final SessionImplSocket session; + private final TObjectIntHashMap backend; + + ObjectResourceMap(SessionImplSocket session) { + this.session = session; + backend = new TObjectIntHashMap<>(Constants.DEFAULT_CAPACITY, Constants.DEFAULT_LOAD_FACTOR, 0); + } + + ObjectResourceMap(SessionImplSocket session, int capacity) { + this.session = session; + backend = new TObjectIntHashMap<>(capacity, Constants.DEFAULT_LOAD_FACTOR, 0); + } + + @Override + public int size() { + return backend.size(); + } + @Override + public boolean isEmpty() { + return backend.isEmpty(); + } + + @Override + public boolean containsKey(Object key) { + return backend.contains(key); + } + + @Override + public boolean containsValue(Object value) { + ResourceImpl impl = (ResourceImpl) value; + return backend.containsValue(impl.id); + } + + @Override + public Resource get(Object key) { + try { + int result = backend.get(key); + if (result == 0) + return null; + return session.getResourceByKey(result); + } catch (ResourceNotFoundException e) { + e.printStackTrace(); + } + return null; + } + + @Override + public Resource put(T key, Resource value) { + ResourceImpl impl = (ResourceImpl) value; + int i = backend.put(key, impl.id); + if (i == 0) + return null; + else + try { + return session.getResourceByKey(i); + } catch (ResourceNotFoundException e) { + e.printStackTrace(); + } + return null; + } + + @Override + public Resource remove(Object key) { + throw new UnsupportedOperationException("remove not supported, structure is immutable"); + } + + @Override + public void putAll(Map map) { + @SuppressWarnings("unchecked") + ObjectResourceMap other = (ObjectResourceMap) map; + other.backend.forEachEntry(new TObjectIntProcedure() { + + @Override + public boolean execute(T a, int b) { + backend.put(a, b); + return true; + } + }); + } + + @Override + public void clear() { + throw new UnsupportedOperationException("clear not supported, structure is immutable"); + } + + @Override + public Set keySet() { + final Set result = new HashSet<>(); + backend.forEach(new TObjectProcedure() { + + @Override + public boolean execute(T object) { + result.add(object); + return true; + } + }); + return result; + } + + @Override + public Collection values() { + ArrayList result = new ArrayList<>(); + for (int key : backend.values()) { + try { + result.add(session.getResourceByKey(key)); + } catch (ResourceNotFoundException e) { + e.printStackTrace(); + } + } + return result; + } + + @Override + public Set> entrySet() { + final HashSet> result = new HashSet<>(); + backend.forEachEntry(new TObjectIntProcedure() { + + @Override + public boolean execute(final T a, final int b) { + return result.add(new Map.Entry() { + + @Override + public T getKey() { + return a; + } + + @Override + public Resource getValue() { + return new ResourceImpl(session.resourceSupport, b); + } + + @Override + public Resource setValue(Resource value) { + throw new UnsupportedOperationException("Map.Entry.setValue not supported, structure is immutable"); + } + + }); + } + }); + return result; + } + + @Override + public int hashCode() { + return backend.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) { + if (obj instanceof Map) { + // Nonoptimal fallback for comparing against generic Map + Map m = (Map) obj; + if (m.size() != size()) + return false; + try { + Iterator> i = entrySet().iterator(); + while (i.hasNext()) { + Entry e = i.next(); + T key = e.getKey(); + Resource value = e.getValue(); + if (value == null) { + if (!(m.get(key)==null && m.containsKey(key))) + return false; + } else { + if (!value.equals(m.get(key))) + return false; + } + } + return true; + } catch (ClassCastException unused) { + return false; + } catch (NullPointerException unused) { + return false; + } + } + return false; + } + ObjectResourceMap other = (ObjectResourceMap) obj; + return session == other.session && backend.equals(other.backend); + } + + @Override + public void putId(T t, int r) { + backend.put(t, r); + } + + @Override + public int getId(T t) { + return backend.get(t); + } + +} \ No newline at end of file