]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ClusterBuilderImpl2.java
Merge commit '55ca14c'
[simantics/platform.git] / bundles / org.simantics.db.procore / src / fi / vtt / simantics / procore / internal / ClusterBuilderImpl2.java
1 package fi.vtt.simantics.procore.internal;\r
2 \r
3 import org.simantics.db.Resource;\r
4 import org.simantics.db.WriteOnlyGraph;\r
5 import org.simantics.db.exception.DatabaseException;\r
6 import org.simantics.db.exception.RuntimeDatabaseException;\r
7 import org.simantics.db.impl.ClusterSupport;\r
8 import org.simantics.db.impl.ClusterTraitsBase;\r
9 import org.simantics.db.impl.ResourceImpl;\r
10 import org.simantics.db.impl.graph.WriteGraphImpl;\r
11 import org.simantics.db.procore.cluster.ClusterImpl;\r
12 import org.simantics.db.service.ClusterBuilder2;\r
13 import org.simantics.db.service.SerialisationSupport;\r
14 \r
15 import fi.vtt.simantics.procore.internal.SessionImplSocket.WriteOnlySupport;\r
16 \r
17 public class ClusterBuilderImpl2 implements ClusterBuilder2 {\r
18 \r
19     final private ClusterSupport cs;\r
20     final private SerialisationSupport ss;\r
21     final private ClusterStream stream;\r
22     final private WriteOnlySupport support;\r
23     final private ClusterImpl[] clusterArray;\r
24     private boolean allowImmutables;\r
25     \r
26     ClusterBuilderImpl2(SessionImplSocket session, boolean allowImmutables) {\r
27 \r
28         WriteState<?> state = session.writeState;\r
29         if(state != null) {\r
30             WriteGraphImpl graph = state.getGraph();\r
31             support = (WriteOnlySupport)graph.writeSupport;\r
32             stream = support.stream;\r
33         } else {\r
34             support = null;\r
35             stream = null;\r
36         }\r
37         \r
38         this.ss = session.getService(SerialisationSupport.class);\r
39         this.clusterArray = session.clusterTable.getClusterArray();\r
40         this.cs = session.getService(ClusterSupport.class);\r
41         this.allowImmutables = allowImmutables;\r
42         \r
43     }\r
44 \r
45     ClusterBuilderImpl2(SessionImplSocket session) {\r
46         this(session, false);\r
47     }\r
48 \r
49     @Override\r
50     public void newCluster() throws DatabaseException {\r
51         support.flushCluster();\r
52     }\r
53 \r
54     @Override\r
55     public void selectCluster(long cluster) throws DatabaseException {\r
56         support.selectCluster(cluster);\r
57     }\r
58     \r
59     @Override\r
60     public void newCluster(int setHandle) throws DatabaseException {\r
61         support.setDefaultClusterSet(resource(setHandle));\r
62         support.flushCluster();\r
63     }\r
64     \r
65     @Override\r
66     public void createClusterSet(int resource) throws DatabaseException {\r
67         support.createClusterSet(null, resource(resource));\r
68     }\r
69     \r
70     @Override\r
71     public int newResource() throws DatabaseException {\r
72         Resource result = support.createResource(null); \r
73         return handle(result);\r
74     }\r
75 \r
76     @Override\r
77     public int newResource(int set) throws DatabaseException {\r
78         Resource result = support.createResource(null, resource(set));\r
79         return ss.getTransientId(result);\r
80     }\r
81     \r
82     @Override\r
83     public int resource(Resource res) throws DatabaseException {\r
84         ResourceImpl r = (ResourceImpl)res;\r
85         int clusterKey = ClusterTraitsBase.getClusterKeyFromResourceKeyNoThrow(r.id);\r
86         ClusterImpl cluster = clusterArray[clusterKey];\r
87         if(cluster.cc == null) cluster.cc = new ClusterChange(stream, cluster);\r
88         return r.id;\r
89     }\r
90 \r
91     @Override\r
92     public void addStatement(WriteOnlyGraph graph, int subject, int predicate, int object) throws DatabaseException {\r
93         int clusterKey = ClusterTraitsBase.getClusterKeyFromResourceKeyNoThrow(subject);\r
94         ClusterImpl cluster = clusterArray[clusterKey];\r
95         if(!cluster.isLoaded()) cluster = (ClusterImpl)cs.getClusterByResourceKey(subject);\r
96         if(cluster.isWriteOnly()) addStatement(cluster, subject, predicate, object);\r
97         else {\r
98             WriteGraphImpl impl = (WriteGraphImpl)graph;\r
99             if(!cluster.getImmutable() || allowImmutables)\r
100                 impl.writeSupport.claim(graph.getProvider(), subject, predicate, object);\r
101         }\r
102     }\r
103     \r
104     private void addStatement(ClusterImpl cluster, int resourceKey, int predicate, int object) {\r
105         \r
106         if(cluster.getImmutable()) return;\r
107         \r
108         Change change = cluster.change;\r
109         change.addStatementIndex0(resourceKey, ClusterChange.ADD_OPERATION);\r
110         applyPredicate(cluster, predicate);\r
111         applyObject(cluster, object);\r
112         cluster.cc.addChange(change);\r
113         \r
114     }\r
115     \r
116     public void applyPredicate(ClusterImpl impl, int predicate) {\r
117         \r
118         int clusterKey = ClusterTraitsBase.getClusterKeyFromResourceKeyNoThrow(predicate);\r
119         ClusterImpl cluster = clusterArray[clusterKey]; \r
120         \r
121         impl.change.addStatementIndex1(predicate, cluster.clusterUID, (byte)0, impl.foreignLookup);\r
122         \r
123     }\r
124 \r
125     public void applyObject(ClusterImpl impl, int object) {\r
126 \r
127         int clusterKey = ClusterTraitsBase.getClusterKeyFromResourceKeyNoThrow(object);\r
128         ClusterImpl cluster = clusterArray[clusterKey]; \r
129         \r
130         impl.change.addStatementIndex2(object, cluster.clusterUID, (byte)0, impl.foreignLookup);\r
131         \r
132     }\r
133 \r
134     @Override\r
135     public Resource resource(int key) {\r
136         try {\r
137             return ss.getResource(key);\r
138         } catch (DatabaseException e) {\r
139             throw new RuntimeDatabaseException(e);\r
140         }\r
141     }\r
142     \r
143     @Override\r
144     public int handle(Resource r) {\r
145         return ((ResourceImpl)r).id;\r
146     }\r
147 \r
148     byte[] buffer = new byte[65536];\r
149     int bufferOffset = 0;\r
150     int valueSubject = 0;\r
151     int valueOffset = 0;\r
152     \r
153     @Override\r
154     public void beginValue(int subject) {\r
155         valueSubject = subject;\r
156         bufferOffset = 0;\r
157         valueOffset = 0;\r
158     }\r
159         \r
160     @Override\r
161     public void appendValue(int byteValue) throws DatabaseException {\r
162         buffer[bufferOffset++] = (byte)byteValue;\r
163         if(bufferOffset == 65536) {\r
164             int clusterKey = ClusterTraitsBase.getClusterKeyFromResourceKeyNoThrow(valueSubject);\r
165             ClusterImpl cluster = clusterArray[clusterKey]; \r
166             cluster.modiValueEx(valueSubject, valueOffset, 65536, buffer, 0, cs);\r
167             bufferOffset = 0;\r
168             valueOffset += 65536;\r
169         }\r
170     }\r
171 \r
172     @Override\r
173     public void endValue() throws DatabaseException {\r
174         if(bufferOffset > 0) {\r
175             int clusterKey = ClusterTraitsBase.getClusterKeyFromResourceKeyNoThrow(valueSubject);\r
176             ClusterImpl cluster = clusterArray[clusterKey]; \r
177             if(valueOffset == 0) {\r
178                 if(cluster.isWriteOnly()) cluster.cc.setValue((short)(valueSubject & 0xFFF), buffer, bufferOffset);\r
179                 else {\r
180                     support.claimValue(null, valueSubject, buffer, bufferOffset);\r
181                 }\r
182             } else {\r
183                 cluster.modiValueEx(valueSubject, valueOffset, bufferOffset, buffer, 0, cs);\r
184             }\r
185         }\r
186     }\r
187     \r
188 }\r