]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.graph/src/org/simantics/graph/store/ValueStore.java
Fixed multiple issues causing dangling references to discarded queries
[simantics/platform.git] / bundles / org.simantics.graph / src / org / simantics / graph / store / ValueStore.java
1 package org.simantics.graph.store;
2
3 import gnu.trove.map.hash.TIntIntHashMap;
4 import gnu.trove.map.hash.TIntObjectHashMap;
5 import gnu.trove.procedure.TIntObjectProcedure;
6 import gnu.trove.procedure.TIntProcedure;
7 import gnu.trove.set.hash.TIntHashSet;
8
9 import java.util.ArrayList;
10
11 import org.simantics.databoard.Bindings;
12 import org.simantics.databoard.adapter.AdaptException;
13 import org.simantics.databoard.binding.Binding;
14 import org.simantics.databoard.binding.mutable.Variant;
15 import org.simantics.databoard.serialization.Serializer;
16 import org.simantics.databoard.type.Datatype;
17 import org.simantics.graph.representation.Value;
18
19 public class ValueStore implements IStore {
20         
21         public static Binding DatatypeBinding =
22                 Bindings.getBindingUnchecked(Datatype.class);
23         public static Serializer DatatypeSerializer =
24                 Bindings.getSerializerUnchecked(DatatypeBinding);
25         
26         TIntObjectHashMap<Variant> byteValues = new TIntObjectHashMap<Variant>();
27         TIntObjectHashMap<Datatype> datatypeValues = new TIntObjectHashMap<Datatype>();
28         TIntHashSet collisions = new TIntHashSet();
29         
30         public void map(final TIntIntHashMap map) {
31                 collisions = IndexMappingUtils.map(map, collisions);
32                 byteValues = IndexMappingUtils.map(map, byteValues, collisions);
33                 datatypeValues = IndexMappingUtils.map(map, datatypeValues, collisions);
34         }
35         
36         public void setValue(int id, Variant value) {
37                 if(byteValues.put(id, value) != null)
38                         collisions.add(id);
39         }
40         
41         public void setValue(int id, Datatype value) {
42                 datatypeValues.put(id, value);
43         }
44
45         public Variant getByteValue(int id) {
46                 return byteValues.get(id);
47         }
48         
49         private static final Binding DATATYPE_BINDING = 
50                 Bindings.getBindingUnchecked(Datatype.class);
51         
52         public Datatype getDatatypeValue(int id) {
53                 Datatype datatype = datatypeValues.get(id);
54                 if(datatype == null) {
55                         Variant bytes = byteValues.get(id);
56                         if(bytes != null)
57                                 try {
58                                         return (Datatype)bytes.getValue(DATATYPE_BINDING);
59                                 } catch (AdaptException e) {
60                                         throw new RuntimeException(e);
61                                 }
62                 }
63                 return datatype;
64         }
65
66         public Value[] toArray() {
67                 final ArrayList<Value> values = new ArrayList<Value>();
68                 byteValues.forEachEntry(new TIntObjectProcedure<Variant>() {
69                         @Override
70                         public boolean execute(int a, Variant b) {
71                                 values.add(new Value(a, b));
72                                 return true;
73                         }
74                 });
75                 datatypeValues.forEachEntry(new TIntObjectProcedure<Datatype>() {
76                     Binding datatypeBinding = Bindings.getBindingUnchecked(Datatype.class);
77                         @Override
78                         public boolean execute(int a, Datatype b) {
79                                 if(!byteValues.containsKey(a))
80                                         try {
81                                                 if(b == null)
82                                                         System.out.println("Resource " + a + " has null Datatype value.");
83                                                 else
84                                                         values.add(new Value(a, new Variant(datatypeBinding, b)));
85                                         } catch (Exception e) {
86                                                 throw new RuntimeException(e);
87                                         }
88                                 return true;
89                         }
90                 });
91                 return values.toArray(new Value[values.size()]);
92         }
93         
94         public void collectReferences(final boolean[] set) {
95                 TIntProcedure proc = new TIntProcedure() {                      
96                         @Override
97                         public boolean execute(int value) {
98                                 set[value] = true;
99                                 return true;
100                         }
101                 };
102                 
103                 byteValues.forEach(proc);
104                 datatypeValues.forEach(proc);
105         }
106         
107         public TIntHashSet getCollisions() {
108                 datatypeValues.forEachKey(new TIntProcedure() {
109                         @Override
110                         public boolean execute(int value) {
111                                 if(byteValues.containsKey(value))
112                                         collisions.add(value);
113                                 return true;
114                         }
115                 });
116                 return collisions;
117         }
118 }