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