1 package org.simantics.graph.representation;
3 import java.io.DataInput;
4 import java.io.DataInputStream;
6 import java.io.IOException;
7 import java.io.InputStream;
8 import java.nio.ByteBuffer;
9 import java.nio.channels.ReadableByteChannel;
10 import java.util.ArrayList;
11 import java.util.List;
13 import org.simantics.databoard.Bindings;
14 import org.simantics.databoard.Datatypes;
15 import org.simantics.databoard.binding.error.RuntimeDatatypeConstructionException;
16 import org.simantics.databoard.binding.mutable.Variant;
17 import org.simantics.databoard.container.DataContainers;
18 import org.simantics.databoard.serialization.RuntimeSerializerConstructionException;
19 import org.simantics.databoard.serialization.Serializer;
20 import org.simantics.databoard.type.Datatype;
23 final public class TransferableGraphFileReader extends ByteFileReader {
25 InputStream in = new InputStream() {
28 public int read() throws IOException {
33 public int read(byte[] b) throws IOException {
34 // FIXME not correctly implemented
35 System.arraycopy(safeBytes(b.length), 0, b, 0, b.length);
40 public int read(byte[] b, int off, int len) throws IOException {
41 // FIXME not correctly implemented
42 System.arraycopy(safeBytes(len), 0, b, off, len);
49 final static class InputChannel implements ReadableByteChannel {
51 final private InputStream stream;
53 public InputChannel(InputStream stream) {
58 public boolean isOpen() {
63 public void close() throws IOException {
67 public int read(ByteBuffer dst) throws IOException {
68 int pos = dst.position();
69 int limit = dst.limit();
70 int i=stream.read(dst.array(), pos, limit-pos);
71 //System.err.println("Read " + i + " (expected " + dst.array().length + ")");
77 private static boolean init = true;
79 final private static int SIZE = 1<<18;
80 final private static int HEADER = headerSize();
81 final private int header;
83 public TransferableGraphFileReader(File file) throws IOException {
87 TransferableGraphFileReader r = new TransferableGraphFileReader(file, 0);
88 for(int i=0;i<40000;i++) r.readTG();
93 public TransferableGraphFileReader(InputStream stream) throws IOException {
94 super(null, new InputChannel(stream), SIZE);
97 TransferableGraphFileReader r = new TransferableGraphFileReader(stream, 0);
98 for(int i=0;i<40000;i++) r.readTG();
103 public TransferableGraphFileReader(ReadableByteChannel channel) throws IOException {
104 super(null, channel, SIZE);
107 TransferableGraphFileReader r = new TransferableGraphFileReader(channel, 0);
108 for(int i=0;i<40000;i++) r.readTG();
113 public TransferableGraphFileReader(ReadableByteChannel channel, int size) throws IOException {
114 super(null, channel, SIZE);
118 public TransferableGraphFileReader(InputStream stream, int size) throws IOException {
119 super(null, new InputChannel(stream), size);
123 public TransferableGraphFileReader(File file, int size) throws IOException {
125 this.header = HEADER;
128 private static int headerSize() {
130 return Bindings.getSerializerUnchecked(Datatype.class).serialize(Datatypes.getDatatypeUnchecked(TransferableGraph1.class)).length;
131 } catch (RuntimeSerializerConstructionException e) {
132 throw new Error("Failed to determine TransferableGraph1 header size. ", e);
133 } catch (RuntimeDatatypeConstructionException e) {
134 throw new Error("Failed to determine TransferableGraph1 header size. ", e);
135 } catch (IOException e) {
136 throw new Error("Failed to determine TransferableGraph1 header size. ", e);
140 public TransferableGraph1 readTG() throws IOException {
142 if(getSize() == 0) return null;
144 // long start = System.nanoTime();
146 final byte[] bytes = getBytes();
148 // byteIndex = header;
150 DataInputStream dis = new DataInputStream(in);
153 DataContainers.readHeader(dis);
155 // Content variant data type
156 Bindings.getSerializerUnchecked(Datatype.class).deserialize((DataInput)dis);
158 int resourceCount = safeInt();
160 List<Object> idcontext = new ArrayList<Object>();
161 dis = new DataInputStream(in);
162 Extensions extensions = (Extensions)Bindings.getSerializerUnchecked(Extensions.class).deserialize((DataInput)dis, idcontext);
164 int identities = safeInt();
165 Identity[] ids = new Identity[identities];
167 // System.err.println("rc: " + resourceCount);
168 // System.err.println("ids: " + identities);
170 // long duration = System.nanoTime() - start;
171 // System.err.println("start in " + 1e-9*duration + "s.");
172 // start = System.nanoTime();
174 for(int i=0;i<identities;i++) {
176 byte type = bytes[byteIndex++];
180 int parent = safeInt();
181 int nameLen = getDynamicUInt32();
183 if(byteIndex+nameLen < SIZE) {
184 ids[i] = new Identity(rid, new External(parent, utf(bytes, byteIndex, byteIndex + nameLen)));
185 byteIndex += nameLen;
187 ids[i] = new Identity(rid, new External(parent, utf(safeBytes(nameLen), 0, nameLen)));
194 int parent = safeInt();
195 int nameLen = getDynamicUInt32();
196 if(byteIndex+nameLen < SIZE) {
197 ids[i] = new Identity(rid, new Internal(parent, utf(bytes, byteIndex, byteIndex + nameLen)));
198 byteIndex += nameLen;
200 ids[i] = new Identity(rid, new Internal(parent, utf(safeBytes(nameLen), 0, nameLen)));
206 int nameLen = getDynamicUInt32();
207 String name = utf(safeBytes(nameLen), 0, nameLen);
208 int nameLen2 = getDynamicUInt32();
209 String rType = utf(safeBytes(nameLen2), 0, nameLen2);
210 ids[i] = new Identity(rid, new Root(name, rType));
212 } else if(type == 2) {
213 throw new UnsupportedOperationException();
218 // for(Identity id : ids) System.err.println("id: " + id);
221 // duration = System.nanoTime() - start;
222 // System.err.println("ids in " + 1e-9*duration + "s.");
223 // start = System.nanoTime();
225 int stmLength = safeInt();
226 // System.err.println("statements: " + stmLength + " (" + byteIndex + ")");
228 int[] statements = new int[stmLength];
230 for(int stmIndex=0;stmIndex<stmLength;) {
232 statements[stmIndex++] = safeInt();
235 int avail = (SIZE-byteIndex) >> 2;
236 int allowed = Math.min(stmLength-stmIndex, avail);
237 for(int index = byteIndex, i=0;i<allowed;i++) {
238 statements[stmIndex++] = ((bytes[index++]&0xff)<<24) | ((bytes[index++]&0xff)<<16) | ((bytes[index++]&0xff)<<8) | ((bytes[index++]&0xff));
240 byteIndex += allowed<<2;
244 // duration = System.nanoTime() - start;
245 // System.err.println("stms in " + 1e-9*duration + "s.");
247 // start = System.nanoTime();
249 int valueLength = safeInt();
250 // System.err.println("values: " + valueLength + " (" + byteIndex + ")");
252 Value[] values = new Value[valueLength];
254 Serializer variantSerializer = Bindings.getSerializerUnchecked(Bindings.VARIANT);
256 idcontext = new ArrayList<Object>();
257 dis = new DataInputStream(in);
259 for(int i=0;i<valueLength;i++) {
260 int resource = safeInt();
261 Variant value = (Variant)variantSerializer
262 .deserialize((DataInput)dis, idcontext);
263 values[i] = new Value(resource, value);
265 //System.err.println("read variant[" + resource + "]: " + value.toString().substring(0, Math.min(100, value.toString().length())));
270 // duration = System.nanoTime() - start;
271 // System.err.println("values in " + 1e-9*duration + "s.");
273 return new TransferableGraph1(resourceCount, ids, statements, values, extensions.map);
277 public static void main(String[] args) {
281 File file = new File("c:/users/antti villberg/desktop/test.apros");
282 TransferableGraphFileReader reader = new TransferableGraphFileReader(file, SIZE);
283 reader = new TransferableGraphFileReader(file);
284 long s = System.nanoTime();
286 long d = System.nanoTime() - s;
287 System.err.println("Duration=" + 1e-9*d + "s.");
290 } catch (Throwable t) {