1 /*******************************************************************************
\r
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
\r
3 * in Industry THTH ry.
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.layer0.utils.writer;
\r
15 import gnu.trove.map.hash.TIntIntHashMap;
\r
16 import gnu.trove.map.hash.TIntLongHashMap;
\r
18 import java.io.BufferedInputStream;
\r
19 import java.io.BufferedOutputStream;
\r
20 import java.io.File;
\r
21 import java.io.FileInputStream;
\r
22 import java.io.FileOutputStream;
\r
23 import java.io.IOException;
\r
24 import java.io.ObjectInputStream;
\r
25 import java.io.ObjectOutputStream;
\r
26 import java.nio.channels.FileChannel;
\r
28 import org.eclipse.core.runtime.IProgressMonitor;
\r
29 import org.simantics.db.ReadGraph;
\r
30 import org.simantics.db.Resource;
\r
31 import org.simantics.db.WriteOnlyGraph;
\r
32 import org.simantics.db.exception.DatabaseException;
\r
34 public class DelayedGraphWriter extends AbstractDelayedGraphWriter {
\r
36 protected File file;
\r
37 protected ObjectOutputStream s;
\r
38 TIntIntHashMap clusterHints = new TIntIntHashMap();
\r
39 TIntLongHashMap clusterIds = new TIntLongHashMap();
\r
41 public DelayedGraphWriter(ReadGraph graph) {
\r
44 file = File.createTempFile("graph", ".tmp");
\r
45 System.out.println("Temp file: " + file.getAbsolutePath());
\r
46 s = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file), 1024*1024));
\r
47 // s = new ObjectOutputStream(backup);
\r
49 file.deleteOnExit();
\r
50 } catch (IOException e) {
\r
51 throw new RuntimeException("Opening output stream to temporary file failed", e);
\r
55 private void writeRef(int ref) throws IOException {
\r
57 timestamps.set(ref-1, time++);
\r
62 public GraphWriter let(Resource p, Resource o) throws DatabaseException {
\r
68 writeRef(getPredicateId(p));
\r
70 } catch (IOException e) {
\r
71 throw new RuntimeException("Writing statement failed.", e);
\r
77 public GraphWriter let(Resource p, Object value, Resource dataType) throws DatabaseException {
\r
79 assert(value != null);
\r
80 assert(dataType != null);
\r
86 writeRef(internalCount);
\r
87 s.writeUnshared(value);
\r
88 writeRef(getId(dataType));
\r
92 writeRef(getPredicateId(p));
\r
93 writeRef(internalCount);
\r
94 } catch (IOException e) {
\r
95 throw new RuntimeException("Writing statement failed.", e);
\r
101 public GraphWriter let(int clusterHint, Resource p, Object value,
\r
102 Resource dataType) throws DatabaseException {
\r
103 let(p, value, dataType);
\r
104 clusterHints.put(internalCount, clusterHint);
\r
109 public GraphWriter createLiteral(Object value, Resource dataType) {
\r
110 assert(value != null);
\r
111 assert(dataType != null);
\r
117 writeRef(internalCount);
\r
118 s.writeUnshared(value);
\r
119 writeRef(getId(dataType));
\r
121 current = internalCount;
\r
122 } catch (IOException e) {
\r
123 throw new RuntimeException("Writing statement failed.", e);
\r
129 public GraphWriter createLiteral(int clusterHint, Object value,
\r
130 Resource dataType) {
\r
131 createLiteral(value, dataType);
\r
133 clusterHints.put(current, clusterHint);
\r
138 public GraphWriter createInverse(int cluster, Resource r) {
\r
144 writeRef(getId(r));
\r
145 } catch (IOException e) {
\r
146 throw new RuntimeException("Writing statement failed.", e);
\r
152 public GraphWriter createInverse(Resource r) {
\r
158 writeRef(getId(r));
\r
159 } catch (IOException e) {
\r
160 throw new RuntimeException("Writing statement failed.", e);
\r
165 protected Resource getResource(WriteOnlyGraph wg, Resource[] internals, long[] resourceIds, int id) {
\r
167 Resource ret = internals[id-1];
\r
169 throw new Error("Error");
\r
170 // ret = wg.newResource(types.get(id));
\r
171 // internals[id-1] = ret;
\r
172 // resourceIds[id-1] = ret.getResourceId();
\r
174 if(timestamps.getQuick(id-1)==time)
\r
175 internals[id-1] = null;
\r
180 return externals.get(-1-id);
\r
187 public void commit(IProgressMonitor monitor, WriteOnlyGraph wg) throws DatabaseException {
\r
194 externalsInv = null;
\r
196 monitor.beginTask("", 100);
\r
198 int lastPercentageDone = 0;
\r
199 long fileLength = file.length();
\r
201 // System.out.println("size of commit file: " + fileLength);
\r
203 Resource[] internals = new Resource[internalCount];
\r
204 resourceIds = new long[internalCount];
\r
207 FileInputStream fis = new FileInputStream(file);
\r
208 FileChannel fc = fis.getChannel();
\r
209 ObjectInputStream is = new ObjectInputStream(new BufferedInputStream(fis, 1024*1024));
\r
210 int resourceCounter = 0;
\r
211 int statementCounter = 0;
\r
212 int valueCounter = 0;
\r
214 loop: while(true) {
\r
215 switch(is.read()) {
\r
219 int s = is.readInt();
\r
220 int p = is.readInt();
\r
221 int o = is.readInt();
\r
222 Resource rs = getResource(wg, internals, resourceIds, s);
\r
223 Resource rp = getResource(wg, internals, resourceIds, p);
\r
224 Resource ro = getResource(wg, internals, resourceIds, o);
\r
225 Resource rpInv = inverses.get(p);
\r
226 wg.claim(rs, rp, rpInv, ro);
\r
227 statementCounter += 2;
\r
230 int id = is.readInt();
\r
231 Object value = is.readUnshared();
\r
232 int type = is.readInt();
\r
234 Resource r = newResource(wg, internals, id);
\r
235 wg.claim(r, l0.InstanceOf, null, getResource(wg, internals, resourceIds, type));
\r
236 wg.claimValue(r, value);
\r
237 statementCounter ++;
\r
238 resourceCounter ++;
\r
247 int s = is.readInt();
\r
248 int t = is.readInt();
\r
250 Resource type = getResource(wg, internals, resourceIds, t);
\r
251 wg.claim(newResource(wg, internals, s), l0.InstanceOf, null, type);
\r
252 statementCounter ++;
\r
253 resourceCounter ++;
\r
258 int s = is.readInt();
\r
259 newResource(wg, internals, s);
\r
260 resourceCounter ++;
\r
263 case 5: { // InverseOf
\r
265 int r1 = is.readInt();
\r
266 int r2 = is.readInt();
\r
268 Resource rr1 = getResource(wg, internals, resourceIds, r1);
\r
269 Resource rr2 = getResource(wg, internals, resourceIds, r2);
\r
270 wg.claim(rr1, l0.InverseOf, l0.InverseOf, rr2);
\r
271 statementCounter += 2;
\r
273 inverses.put(r1, rr2);
\r
274 inverses.put(r2, rr1);
\r
279 // if((counter % 200000) == 0) {
\r
280 // System.out.println("Written " + counter + " statements.");
\r
283 double percentageDone = 100.0 * (double) fc.position() / (double) fileLength;
\r
284 int newPercentageDone = (int) Math.round(percentageDone);
\r
285 if(newPercentageDone > lastPercentageDone) {
\r
286 monitor.setTaskName("Writing database (" + newPercentageDone + "%)");
\r
287 monitor.worked(newPercentageDone - lastPercentageDone);
\r
288 lastPercentageDone = newPercentageDone;
\r
292 System.out.println("clusterIds.size() = " + clusterIds.size());
\r
294 System.out.println("Wrote " + resourceCounter + " resources, " + statementCounter + " statements and " + valueCounter + " values.");
\r
296 } catch (IOException e) {
\r
297 throw new RuntimeException("Commiting delayed graph writings failed.", e);
\r
298 } catch (ClassNotFoundException e) {
\r
299 throw new RuntimeException("Commiting delayed graph writings failed.", e);
\r
306 private Resource newResource(WriteOnlyGraph wg, Resource[] internals, int s) throws DatabaseException {
\r
307 int clusterHint = clusterHints.get(s);
\r
310 if(clusterHint == 0)
\r
311 r = wg.newResource();
\r
313 long clusterId = clusterIds.get(clusterHint);
\r
314 if(clusterId == 0) {
\r
316 r = wg.newResource();
\r
317 clusterIds.put(clusterHint, clustering.getCluster(r));
\r
320 r = wg.newResource(clusterId);
\r
322 internals[s-1] = r;
\r
323 resourceIds[s-1] = r.getResourceId();
\r
327 // public ValueDescriptor createDescriptor(Object obj) {
\r
329 // if(obj instanceof String[])
\r
330 // return new ValueDescriptor(ValueTrait.StaticValue, (String[])obj);
\r
331 // else if(obj instanceof int[])
\r
332 // return new ValueDescriptor(ValueTrait.StaticValue, (int[])obj);
\r
333 // else if(obj instanceof double[])
\r
334 // return new ValueDescriptor(ValueTrait.StaticValue, (double[])obj);
\r
335 // else if(obj instanceof float[])
\r
336 // return new ValueDescriptor(ValueTrait.StaticValue, (float[])obj);
\r
337 // else if(obj instanceof boolean[])
\r
338 // return new ValueDescriptor(ValueTrait.StaticValue, (boolean[])obj);
\r
339 // else if(obj instanceof long[])
\r
340 // return new ValueDescriptor(ValueTrait.StaticValue, (long[])obj);
\r
341 // else if(obj instanceof byte[])
\r
342 // return new ValueDescriptor(ValueTrait.StaticValue, (byte[])obj);
\r
344 // else if(obj instanceof String)
\r
345 // return new ValueDescriptor(ValueTrait.StaticValue, new String[] {(String)obj});
\r
346 // else if(obj instanceof Double)
\r
347 // return new ValueDescriptor(ValueTrait.StaticValue, new double[] {(Double)obj});
\r
348 // else if(obj instanceof Float)
\r
349 // return new ValueDescriptor(ValueTrait.StaticValue, new float[] {(Float)obj});
\r
350 // else if(obj instanceof Integer)
\r
351 // return new ValueDescriptor(ValueTrait.StaticValue, new int[] {(Integer)obj});
\r
352 // else if(obj instanceof Boolean)
\r
353 // return new ValueDescriptor(ValueTrait.StaticValue, new boolean[] {(Boolean)obj});
\r
354 // else if(obj instanceof Byte)
\r
355 // return new ValueDescriptor(ValueTrait.StaticValue, new byte[] {(Byte)obj});
\r
356 // else if(obj instanceof Long)
\r
357 // return new ValueDescriptor(ValueTrait.StaticValue, new long[] {(Long)obj});
\r
359 // throw new Error("Wrong type!");
\r
364 public GraphWriter create() {
\r
366 current = ++internalCount;
\r
371 s.writeInt(current);
\r
372 } catch (IOException e) {
\r
373 throw new RuntimeException("Writing statement failed.", e);
\r
381 public GraphWriter create(int clusterHint) {
\r
384 clusterHints.put(current, clusterHint);
\r
390 public GraphWriter create(Resource type) {
\r
391 assert(type != null);
\r
393 current = ++internalCount;
\r
398 s.writeInt(current);
\r
399 s.writeInt(getId(type));
\r
400 } catch (IOException e) {
\r
401 throw new RuntimeException("Writing statement failed.", e);
\r
409 public GraphWriter create(int clusterHint, Resource type) {
\r
412 clusterHints.put(current, clusterHint);
\r
418 public Resource get() {
\r
420 return new InternalResource(current);
\r
421 else if(current < 0)
\r
422 return externals.get(-1-current);
\r
428 public GraphWriter handle(Resource s) {
\r
431 current = getId(s);
\r
435 public GraphWriter flush() {
\r
438 } catch(IOException e) {
\r
439 throw new RuntimeException("Writing flush failed.", e);
\r