package org.simantics.graph.store; import gnu.trove.map.hash.TIntIntHashMap; import gnu.trove.map.hash.TIntObjectHashMap; import gnu.trove.procedure.TIntObjectProcedure; import gnu.trove.procedure.TIntProcedure; import gnu.trove.set.hash.TIntHashSet; import java.util.ArrayList; import org.simantics.databoard.Bindings; import org.simantics.databoard.adapter.AdaptException; import org.simantics.databoard.binding.Binding; import org.simantics.databoard.binding.mutable.Variant; import org.simantics.databoard.serialization.Serializer; import org.simantics.databoard.type.Datatype; import org.simantics.graph.representation.Value; public class ValueStore implements IStore { public static Binding DatatypeBinding = Bindings.getBindingUnchecked(Datatype.class); public static Serializer DatatypeSerializer = Bindings.getSerializerUnchecked(DatatypeBinding); TIntObjectHashMap byteValues = new TIntObjectHashMap(); TIntObjectHashMap datatypeValues = new TIntObjectHashMap(); TIntHashSet collisions = new TIntHashSet(); public void map(final TIntIntHashMap map) { collisions = IndexMappingUtils.map(map, collisions); byteValues = IndexMappingUtils.map(map, byteValues, collisions); datatypeValues = IndexMappingUtils.map(map, datatypeValues, collisions); } public void setValue(int id, Variant value) { if(byteValues.put(id, value) != null) collisions.add(id); } public void setValue(int id, Datatype value) { datatypeValues.put(id, value); } public Variant getByteValue(int id) { return byteValues.get(id); } private static final Binding DATATYPE_BINDING = Bindings.getBindingUnchecked(Datatype.class); public Datatype getDatatypeValue(int id) { Datatype datatype = datatypeValues.get(id); if(datatype == null) { Variant bytes = byteValues.get(id); if(bytes != null) try { return (Datatype)bytes.getValue(DATATYPE_BINDING); } catch (AdaptException e) { throw new RuntimeException(e); } } return datatype; } public Value[] toArray() { final ArrayList values = new ArrayList(); byteValues.forEachEntry(new TIntObjectProcedure() { @Override public boolean execute(int a, Variant b) { values.add(new Value(a, b)); return true; } }); datatypeValues.forEachEntry(new TIntObjectProcedure() { Binding datatypeBinding = Bindings.getBindingUnchecked(Datatype.class); @Override public boolean execute(int a, Datatype b) { if(!byteValues.containsKey(a)) try { if(b == null) System.out.println("Resource " + a + " has null Datatype value."); else values.add(new Value(a, new Variant(datatypeBinding, b))); } catch (Exception e) { throw new RuntimeException(e); } return true; } }); return values.toArray(new Value[values.size()]); } public void collectReferences(final boolean[] set) { TIntProcedure proc = new TIntProcedure() { @Override public boolean execute(int value) { set[value] = true; return true; } }; byteValues.forEach(proc); datatypeValues.forEach(proc); } public TIntHashSet getCollisions() { datatypeValues.forEachKey(new TIntProcedure() { @Override public boolean execute(int value) { if(byteValues.containsKey(value)) collisions.add(value); return true; } }); return collisions; } }