--- /dev/null
+package fi.vtt.simantics.procore.internal;\r
+\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteOnlyGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.exception.RuntimeDatabaseException;\r
+import org.simantics.db.impl.ClusterSupport;\r
+import org.simantics.db.impl.ClusterTraitsBase;\r
+import org.simantics.db.impl.ResourceImpl;\r
+import org.simantics.db.impl.graph.WriteGraphImpl;\r
+import org.simantics.db.procore.cluster.ClusterImpl;\r
+import org.simantics.db.service.ClusterBuilder2;\r
+import org.simantics.db.service.SerialisationSupport;\r
+\r
+import fi.vtt.simantics.procore.internal.SessionImplSocket.WriteOnlySupport;\r
+\r
+public class ClusterBuilderImpl2 implements ClusterBuilder2 {\r
+\r
+ final private ClusterSupport cs;\r
+ final private SerialisationSupport ss;\r
+ final private ClusterStream stream;\r
+ final private WriteOnlySupport support;\r
+ final private ClusterImpl[] clusterArray;\r
+ private boolean allowImmutables;\r
+ \r
+ ClusterBuilderImpl2(SessionImplSocket session, boolean allowImmutables) {\r
+\r
+ WriteState<?> state = session.writeState;\r
+ if(state != null) {\r
+ WriteGraphImpl graph = state.getGraph();\r
+ support = (WriteOnlySupport)graph.writeSupport;\r
+ stream = support.stream;\r
+ } else {\r
+ support = null;\r
+ stream = null;\r
+ }\r
+ \r
+ this.ss = session.getService(SerialisationSupport.class);\r
+ this.clusterArray = session.clusterTable.getClusterArray();\r
+ this.cs = session.getService(ClusterSupport.class);\r
+ this.allowImmutables = allowImmutables;\r
+ \r
+ }\r
+\r
+ ClusterBuilderImpl2(SessionImplSocket session) {\r
+ this(session, false);\r
+ }\r
+\r
+ @Override\r
+ public void newCluster() throws DatabaseException {\r
+ support.flushCluster();\r
+ }\r
+\r
+ @Override\r
+ public void selectCluster(long cluster) throws DatabaseException {\r
+ support.selectCluster(cluster);\r
+ }\r
+ \r
+ @Override\r
+ public void newCluster(int setHandle) throws DatabaseException {\r
+ support.setDefaultClusterSet(resource(setHandle));\r
+ support.flushCluster();\r
+ }\r
+ \r
+ @Override\r
+ public void createClusterSet(int resource) throws DatabaseException {\r
+ support.createClusterSet(null, resource(resource));\r
+ }\r
+ \r
+ @Override\r
+ public int newResource() throws DatabaseException {\r
+ Resource result = support.createResource(null); \r
+ return handle(result);\r
+ }\r
+\r
+ @Override\r
+ public int newResource(int set) throws DatabaseException {\r
+ Resource result = support.createResource(null, resource(set));\r
+ return ss.getTransientId(result);\r
+ }\r
+ \r
+ @Override\r
+ public int resource(Resource res) throws DatabaseException {\r
+ ResourceImpl r = (ResourceImpl)res;\r
+ int clusterKey = ClusterTraitsBase.getClusterKeyFromResourceKeyNoThrow(r.id);\r
+ ClusterImpl cluster = clusterArray[clusterKey];\r
+ if(cluster.cc == null) cluster.cc = new ClusterChange(stream, cluster);\r
+ return r.id;\r
+ }\r
+\r
+ @Override\r
+ public void addStatement(WriteOnlyGraph graph, int subject, int predicate, int object) throws DatabaseException {\r
+ int clusterKey = ClusterTraitsBase.getClusterKeyFromResourceKeyNoThrow(subject);\r
+ ClusterImpl cluster = clusterArray[clusterKey];\r
+ if(!cluster.isLoaded()) cluster = (ClusterImpl)cs.getClusterByResourceKey(subject);\r
+ if(cluster.isWriteOnly()) addStatement(cluster, subject, predicate, object);\r
+ else {\r
+ WriteGraphImpl impl = (WriteGraphImpl)graph;\r
+ if(!cluster.getImmutable() || allowImmutables)\r
+ impl.writeSupport.claim(graph.getProvider(), subject, predicate, object);\r
+ }\r
+ }\r
+ \r
+ private void addStatement(ClusterImpl cluster, int resourceKey, int predicate, int object) {\r
+ \r
+ if(cluster.getImmutable()) return;\r
+ \r
+ Change change = cluster.change;\r
+ change.addStatementIndex0(resourceKey, ClusterChange.ADD_OPERATION);\r
+ applyPredicate(cluster, predicate);\r
+ applyObject(cluster, object);\r
+ cluster.cc.addChange(change);\r
+ \r
+ }\r
+ \r
+ public void applyPredicate(ClusterImpl impl, int predicate) {\r
+ \r
+ int clusterKey = ClusterTraitsBase.getClusterKeyFromResourceKeyNoThrow(predicate);\r
+ ClusterImpl cluster = clusterArray[clusterKey]; \r
+ \r
+ impl.change.addStatementIndex1(predicate, cluster.clusterUID, (byte)0, impl.foreignLookup);\r
+ \r
+ }\r
+\r
+ public void applyObject(ClusterImpl impl, int object) {\r
+\r
+ int clusterKey = ClusterTraitsBase.getClusterKeyFromResourceKeyNoThrow(object);\r
+ ClusterImpl cluster = clusterArray[clusterKey]; \r
+ \r
+ impl.change.addStatementIndex2(object, cluster.clusterUID, (byte)0, impl.foreignLookup);\r
+ \r
+ }\r
+\r
+ @Override\r
+ public Resource resource(int key) {\r
+ try {\r
+ return ss.getResource(key);\r
+ } catch (DatabaseException e) {\r
+ throw new RuntimeDatabaseException(e);\r
+ }\r
+ }\r
+ \r
+ @Override\r
+ public int handle(Resource r) {\r
+ return ((ResourceImpl)r).id;\r
+ }\r
+\r
+ byte[] buffer = new byte[65536];\r
+ int bufferOffset = 0;\r
+ int valueSubject = 0;\r
+ int valueOffset = 0;\r
+ \r
+ @Override\r
+ public void beginValue(int subject) {\r
+ valueSubject = subject;\r
+ bufferOffset = 0;\r
+ valueOffset = 0;\r
+ }\r
+ \r
+ @Override\r
+ public void appendValue(int byteValue) throws DatabaseException {\r
+ buffer[bufferOffset++] = (byte)byteValue;\r
+ if(bufferOffset == 65536) {\r
+ int clusterKey = ClusterTraitsBase.getClusterKeyFromResourceKeyNoThrow(valueSubject);\r
+ ClusterImpl cluster = clusterArray[clusterKey]; \r
+ cluster.modiValueEx(valueSubject, valueOffset, 65536, buffer, 0, cs);\r
+ bufferOffset = 0;\r
+ valueOffset += 65536;\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void endValue() throws DatabaseException {\r
+ if(bufferOffset > 0) {\r
+ int clusterKey = ClusterTraitsBase.getClusterKeyFromResourceKeyNoThrow(valueSubject);\r
+ ClusterImpl cluster = clusterArray[clusterKey]; \r
+ if(valueOffset == 0) {\r
+ if(cluster.isWriteOnly()) cluster.cc.setValue((short)(valueSubject & 0xFFF), buffer, bufferOffset);\r
+ else {\r
+ support.claimValue(null, valueSubject, buffer, bufferOffset);\r
+ }\r
+ } else {\r
+ cluster.modiValueEx(valueSubject, valueOffset, bufferOffset, buffer, 0, cs);\r
+ }\r
+ }\r
+ }\r
+ \r
+}\r