1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.layer0.utils.writer;
15 import java.io.BufferedInputStream;
16 import java.io.BufferedOutputStream;
18 import java.io.FileInputStream;
19 import java.io.FileOutputStream;
20 import java.io.IOException;
21 import java.io.ObjectInputStream;
22 import java.io.ObjectOutputStream;
23 import java.nio.channels.FileChannel;
25 import org.eclipse.core.runtime.IProgressMonitor;
26 import org.simantics.db.ReadGraph;
27 import org.simantics.db.Resource;
28 import org.simantics.db.WriteOnlyGraph;
29 import org.simantics.db.exception.DatabaseException;
31 import gnu.trove.map.hash.TIntIntHashMap;
32 import gnu.trove.map.hash.TIntLongHashMap;
34 public class DelayedGraphWriter extends AbstractDelayedGraphWriter {
37 protected ObjectOutputStream s;
38 TIntIntHashMap clusterHints = new TIntIntHashMap();
39 TIntLongHashMap clusterIds = new TIntLongHashMap();
41 public DelayedGraphWriter(ReadGraph graph) {
44 file = File.createTempFile("graph", ".tmp");
45 System.out.println("Temp file: " + file.getAbsolutePath());
46 s = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file), 1024*1024));
47 // s = new ObjectOutputStream(backup);
49 } catch (IOException e) {
50 throw new RuntimeException("Opening output stream to temporary file failed", e);
54 private void writeRef(int ref) throws IOException {
56 timestamps.set(ref-1, time++);
61 public GraphWriter let(Resource p, Resource o) throws DatabaseException {
67 writeRef(getPredicateId(p));
69 } catch (IOException e) {
70 throw new RuntimeException("Writing statement failed.", e);
76 public GraphWriter let(Resource p, Object value, Resource dataType) throws DatabaseException {
78 assert(value != null);
79 assert(dataType != null);
85 writeRef(internalCount);
86 s.writeUnshared(value);
87 writeRef(getId(dataType));
91 writeRef(getPredicateId(p));
92 writeRef(internalCount);
93 } catch (IOException e) {
94 throw new RuntimeException("Writing statement failed.", e);
100 public GraphWriter let(int clusterHint, Resource p, Object value,
101 Resource dataType) throws DatabaseException {
102 let(p, value, dataType);
103 clusterHints.put(internalCount, clusterHint);
108 public GraphWriter createLiteral(Object value, Resource dataType) {
109 assert(value != null);
110 assert(dataType != null);
116 writeRef(internalCount);
117 s.writeUnshared(value);
118 writeRef(getId(dataType));
120 current = internalCount;
121 } catch (IOException e) {
122 throw new RuntimeException("Writing statement failed.", e);
128 public GraphWriter createLiteral(int clusterHint, Object value,
130 createLiteral(value, dataType);
132 clusterHints.put(current, clusterHint);
137 public GraphWriter createInverse(int cluster, Resource r) {
144 } catch (IOException e) {
145 throw new RuntimeException("Writing statement failed.", e);
151 public GraphWriter createInverse(Resource r) {
158 } catch (IOException e) {
159 throw new RuntimeException("Writing statement failed.", e);
164 protected Resource getResource(WriteOnlyGraph wg, Resource[] internals, long[] resourceIds, int id) {
166 Resource ret = internals[id-1];
168 throw new Error("Error");
169 // ret = wg.newResource(types.get(id));
170 // internals[id-1] = ret;
171 // resourceIds[id-1] = ret.getResourceId();
173 if(timestamps.getQuick(id-1)==time)
174 internals[id-1] = null;
179 return externals.get(-1-id);
186 public void commit(IProgressMonitor monitor, WriteOnlyGraph wg) throws DatabaseException {
193 monitor.beginTask("Writing database", 100);
194 FileInputStream fis = new FileInputStream(file);
195 FileChannel fc = fis.getChannel();
196 try (ObjectInputStream is = new ObjectInputStream(new BufferedInputStream(fis, 1024*1024))) {
197 commit(monitor, wg, is, fc);
199 } catch (IOException e) {
200 throw new DatabaseException("Commiting delayed graph writings failed.", e);
201 } catch (ClassNotFoundException e) {
202 throw new DatabaseException("Commiting delayed graph writings failed.", e);
209 private void commit(IProgressMonitor monitor, WriteOnlyGraph wg, ObjectInputStream is, FileChannel fc) throws DatabaseException, IOException, ClassNotFoundException {
210 int lastPercentageDone = 0;
211 long fileLength = file.length();
212 //System.out.println("size of commit file: " + fileLength);
214 Resource[] internals = new Resource[internalCount];
215 resourceIds = new long[internalCount];
217 int resourceCounter = 0;
218 int statementCounter = 0;
219 int valueCounter = 0;
224 System.out.println("clusterIds.size() = " + clusterIds.size());
225 System.out.println("Wrote " + resourceCounter + " resources, " + statementCounter + " statements and " + valueCounter + " values.");
229 int s = is.readInt();
230 int p = is.readInt();
231 int o = is.readInt();
232 Resource rs = getResource(wg, internals, resourceIds, s);
233 Resource rp = getResource(wg, internals, resourceIds, p);
234 Resource ro = getResource(wg, internals, resourceIds, o);
235 Resource rpInv = inverses.get(p);
236 wg.claim(rs, rp, rpInv, ro);
237 statementCounter += 2;
240 int id = is.readInt();
241 Object value = is.readUnshared();
242 int type = is.readInt();
244 Resource r = newResource(wg, internals, id);
245 wg.claim(r, l0.InstanceOf, null, getResource(wg, internals, resourceIds, type));
246 wg.claimValue(r, value);
257 int s = is.readInt();
258 int t = is.readInt();
260 Resource type = getResource(wg, internals, resourceIds, t);
261 wg.claim(newResource(wg, internals, s), l0.InstanceOf, null, type);
268 int s = is.readInt();
269 newResource(wg, internals, s);
273 case 5: { // InverseOf
275 int r1 = is.readInt();
276 int r2 = is.readInt();
278 Resource rr1 = getResource(wg, internals, resourceIds, r1);
279 Resource rr2 = getResource(wg, internals, resourceIds, r2);
280 wg.claim(rr1, l0.InverseOf, l0.InverseOf, rr2);
281 statementCounter += 2;
283 inverses.put(r1, rr2);
284 inverses.put(r2, rr1);
289 // if((counter % 200000) == 0) {
290 // System.out.println("Written " + counter + " statements.");
293 double percentageDone = 100.0 * (double) fc.position() / (double) fileLength;
294 int newPercentageDone = (int) Math.round(percentageDone);
295 if(newPercentageDone > lastPercentageDone) {
296 monitor.setTaskName("Writing database (" + newPercentageDone + "%)");
297 monitor.worked(newPercentageDone - lastPercentageDone);
298 lastPercentageDone = newPercentageDone;
303 private Resource newResource(WriteOnlyGraph wg, Resource[] internals, int s) throws DatabaseException {
304 int clusterHint = clusterHints.get(s);
308 r = wg.newResource();
310 long clusterId = clusterIds.get(clusterHint);
313 r = wg.newResource();
314 clusterIds.put(clusterHint, clustering.getCluster(r));
317 r = wg.newResource(clusterId);
320 resourceIds[s-1] = r.getResourceId();
325 public GraphWriter create() {
327 current = ++internalCount;
333 } catch (IOException e) {
334 throw new RuntimeException("Writing statement failed.", e);
342 public GraphWriter create(int clusterHint) {
345 clusterHints.put(current, clusterHint);
351 public GraphWriter create(Resource type) {
352 assert(type != null);
354 current = ++internalCount;
360 s.writeInt(getId(type));
361 } catch (IOException e) {
362 throw new RuntimeException("Writing statement failed.", e);
370 public GraphWriter create(int clusterHint, Resource type) {
372 clusterHints.put(current, clusterHint);
378 public Resource get() {
380 return new InternalResource(current);
382 return externals.get(-1-current);
388 public GraphWriter handle(Resource s) {
395 public GraphWriter flush() {
398 } catch(IOException e) {
399 throw new RuntimeException("Writing flush failed.", e);