1 package fi.vtt.simantics.procore.internal;
3 import org.simantics.db.Resource;
4 import org.simantics.db.WriteOnlyGraph;
5 import org.simantics.db.exception.DatabaseException;
6 import org.simantics.db.exception.RuntimeDatabaseException;
7 import org.simantics.db.impl.ClusterSupport;
8 import org.simantics.db.impl.ClusterTraitsBase;
9 import org.simantics.db.impl.ResourceImpl;
10 import org.simantics.db.impl.graph.WriteGraphImpl;
11 import org.simantics.db.procore.cluster.ClusterImpl;
12 import org.simantics.db.service.ClusterBuilder2;
13 import org.simantics.db.service.SerialisationSupport;
15 import fi.vtt.simantics.procore.internal.SessionImplSocket.WriteOnlySupport;
17 public class ClusterBuilderImpl2 implements ClusterBuilder2 {
19 final private ClusterSupport cs;
20 final private SerialisationSupport ss;
21 final private ClusterStream stream;
22 final private WriteOnlySupport support;
23 final private ClusterImpl[] clusterArray;
24 private boolean allowImmutables;
26 ClusterBuilderImpl2(SessionImplSocket session, boolean allowImmutables) {
28 WriteState<?> state = session.writeState;
30 WriteGraphImpl graph = state.getGraph();
31 support = (WriteOnlySupport)graph.writeSupport;
32 stream = support.stream;
38 this.ss = session.getService(SerialisationSupport.class);
39 this.clusterArray = session.clusterTable.getClusterArray();
40 this.cs = session.getService(ClusterSupport.class);
41 this.allowImmutables = allowImmutables;
45 ClusterBuilderImpl2(SessionImplSocket session) {
50 public void newCluster() throws DatabaseException {
51 support.flushCluster();
55 public void selectCluster(long cluster) throws DatabaseException {
56 support.selectCluster(cluster);
60 public void newCluster(int setHandle) throws DatabaseException {
61 support.setDefaultClusterSet(resource(setHandle));
62 support.flushCluster();
66 public void createClusterSet(int resource) throws DatabaseException {
67 support.createClusterSet(null, resource(resource));
71 public int newResource() throws DatabaseException {
72 Resource result = support.createResource(null);
73 return handle(result);
77 public int newResource(int set) throws DatabaseException {
78 Resource result = support.createResource(null, resource(set));
79 return ss.getTransientId(result);
83 public int resource(Resource res) throws DatabaseException {
84 ResourceImpl r = (ResourceImpl)res;
85 int clusterKey = ClusterTraitsBase.getClusterKeyFromResourceKeyNoThrow(r.id);
86 ClusterImpl cluster = clusterArray[clusterKey];
87 if(cluster.cc == null) cluster.cc = new ClusterChange(stream, cluster);
92 public void addStatement(WriteOnlyGraph graph, int subject, int predicate, int object) throws DatabaseException {
93 int clusterKey = ClusterTraitsBase.getClusterKeyFromResourceKeyNoThrow(subject);
94 ClusterImpl cluster = clusterArray[clusterKey];
95 if(!cluster.isLoaded()) cluster = (ClusterImpl)cs.getClusterByResourceKey(subject);
96 if(cluster.isWriteOnly()) addStatement(cluster, subject, predicate, object);
98 WriteGraphImpl impl = (WriteGraphImpl)graph;
99 if(!cluster.getImmutable() || allowImmutables)
100 impl.writeSupport.claim(graph.getProvider(), subject, predicate, object);
104 private void addStatement(ClusterImpl cluster, int resourceKey, int predicate, int object) {
106 if(cluster.getImmutable()) return;
108 Change change = cluster.change;
109 change.addStatementIndex0(resourceKey, ClusterChange.ADD_OPERATION);
110 applyPredicate(cluster, predicate);
111 applyObject(cluster, object);
112 cluster.cc.addChange(change);
116 public void applyPredicate(ClusterImpl impl, int predicate) {
118 int clusterKey = ClusterTraitsBase.getClusterKeyFromResourceKeyNoThrow(predicate);
119 ClusterImpl cluster = clusterArray[clusterKey];
121 impl.change.addStatementIndex1(predicate, cluster.clusterUID, (byte)0, impl.foreignLookup);
125 public void applyObject(ClusterImpl impl, int object) {
127 int clusterKey = ClusterTraitsBase.getClusterKeyFromResourceKeyNoThrow(object);
128 ClusterImpl cluster = clusterArray[clusterKey];
130 impl.change.addStatementIndex2(object, cluster.clusterUID, (byte)0, impl.foreignLookup);
135 public Resource resource(int key) {
137 return ss.getResource(key);
138 } catch (DatabaseException e) {
139 throw new RuntimeDatabaseException(e);
144 public int handle(Resource r) {
145 return ((ResourceImpl)r).id;
148 byte[] buffer = new byte[65536];
149 int bufferOffset = 0;
150 int valueSubject = 0;
154 public void beginValue(int subject) {
155 valueSubject = subject;
161 public void appendValue(int byteValue) throws DatabaseException {
162 buffer[bufferOffset++] = (byte)byteValue;
163 if(bufferOffset == 65536) {
164 int clusterKey = ClusterTraitsBase.getClusterKeyFromResourceKeyNoThrow(valueSubject);
165 ClusterImpl cluster = clusterArray[clusterKey];
166 cluster.modiValueEx(valueSubject, valueOffset, 65536, buffer, 0, cs);
168 valueOffset += 65536;
173 public void endValue() throws DatabaseException {
174 if(bufferOffset > 0) {
175 int clusterKey = ClusterTraitsBase.getClusterKeyFromResourceKeyNoThrow(valueSubject);
176 ClusterImpl cluster = clusterArray[clusterKey];
177 if(valueOffset == 0) {
178 if(cluster.isWriteOnly()) cluster.cc.setValue((short)(valueSubject & 0xFFF), buffer, bufferOffset);
180 support.claimValue(null, valueSubject, buffer, bufferOffset);
183 cluster.modiValueEx(valueSubject, valueOffset, bufferOffset, buffer, 0, cs);