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;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
25 final public class TransferableGraphFileReader extends ByteFileReader {
27 private static final Logger LOGGER = LoggerFactory.getLogger(TransferableGraphFileReader.class);
29 InputStream in = new InputStream() {
32 public int read() throws IOException {
37 public int read(byte[] b) throws IOException {
38 // FIXME not correctly implemented
39 System.arraycopy(safeBytes(b.length), 0, b, 0, b.length);
44 public int read(byte[] b, int off, int len) throws IOException {
45 // FIXME not correctly implemented
46 System.arraycopy(safeBytes(len), 0, b, off, len);
53 final static class InputChannel implements ReadableByteChannel {
55 final private InputStream stream;
57 public InputChannel(InputStream stream) {
62 public boolean isOpen() {
67 public void close() throws IOException {
71 public int read(ByteBuffer dst) throws IOException {
72 int pos = dst.position();
73 int limit = dst.limit();
74 int i=stream.read(dst.array(), pos, limit-pos);
75 //LOGGER.warn("Read " + i + " (expected " + dst.array().length + ")");
81 private static boolean init = true;
83 final private static int SIZE = 1<<18;
84 final private static int HEADER = headerSize();
85 final private int header;
87 public TransferableGraphFileReader(File file) throws IOException {
91 TransferableGraphFileReader r = new TransferableGraphFileReader(file, 0);
92 for(int i=0;i<40000;i++) r.readTG();
97 public TransferableGraphFileReader(InputStream stream) throws IOException {
98 super(null, new InputChannel(stream), SIZE);
101 TransferableGraphFileReader r = new TransferableGraphFileReader(stream, 0);
102 for(int i=0;i<40000;i++) r.readTG();
107 public TransferableGraphFileReader(ReadableByteChannel channel) throws IOException {
108 super(null, channel, SIZE);
111 TransferableGraphFileReader r = new TransferableGraphFileReader(channel, 0);
112 for(int i=0;i<40000;i++) r.readTG();
117 public TransferableGraphFileReader(ReadableByteChannel channel, int size) throws IOException {
118 super(null, channel, SIZE);
122 public TransferableGraphFileReader(InputStream stream, int size) throws IOException {
123 super(null, new InputChannel(stream), size);
127 public TransferableGraphFileReader(File file, int size) throws IOException {
129 this.header = HEADER;
132 private static int headerSize() {
134 return Bindings.getSerializerUnchecked(Datatype.class).serialize(Datatypes.getDatatypeUnchecked(TransferableGraph1.class)).length;
135 } catch (RuntimeSerializerConstructionException e) {
136 throw new Error("Failed to determine TransferableGraph1 header size. ", e);
137 } catch (RuntimeDatatypeConstructionException e) {
138 throw new Error("Failed to determine TransferableGraph1 header size. ", e);
139 } catch (IOException e) {
140 throw new Error("Failed to determine TransferableGraph1 header size. ", e);
144 public TransferableGraph1 readTG() throws IOException {
146 if(getSize() == 0) return null;
148 // long start = System.nanoTime();
150 final byte[] bytes = getBytes();
152 // byteIndex = header;
154 DataInputStream dis = new DataInputStream(in);
157 DataContainers.readHeader(dis);
159 // Content variant data type
160 Bindings.getSerializerUnchecked(Datatype.class).deserialize((DataInput)dis);
162 int resourceCount = safeInt();
164 List<Object> idcontext = new ArrayList<Object>();
165 dis = new DataInputStream(in);
166 Extensions extensions = (Extensions)Bindings.getSerializerUnchecked(Extensions.class).deserialize((DataInput)dis, idcontext);
168 int identities = safeInt();
169 Identity[] ids = new Identity[identities];
171 // LOGGER.warn("rc: " + resourceCount);
172 // LOGGER.warn("ids: " + identities);
174 // long duration = System.nanoTime() - start;
175 // LOGGER.warn("start in " + 1e-9*duration + "s.");
176 // start = System.nanoTime();
178 for(int i=0;i<identities;i++) {
180 byte type = bytes[byteIndex++];
184 int parent = safeInt();
185 int nameLen = getDynamicUInt32();
187 if(byteIndex+nameLen < SIZE) {
188 ids[i] = new Identity(rid, new External(parent, utf(bytes, byteIndex, byteIndex + nameLen)));
189 byteIndex += nameLen;
191 ids[i] = new Identity(rid, new External(parent, utf(safeBytes(nameLen), 0, nameLen)));
198 int parent = safeInt();
199 int nameLen = getDynamicUInt32();
200 if(byteIndex+nameLen < SIZE) {
201 ids[i] = new Identity(rid, new Internal(parent, utf(bytes, byteIndex, byteIndex + nameLen)));
202 byteIndex += nameLen;
204 ids[i] = new Identity(rid, new Internal(parent, utf(safeBytes(nameLen), 0, nameLen)));
210 int nameLen = getDynamicUInt32();
211 String name = utf(safeBytes(nameLen), 0, nameLen);
212 int nameLen2 = getDynamicUInt32();
213 String rType = utf(safeBytes(nameLen2), 0, nameLen2);
214 ids[i] = new Identity(rid, new Root(name, rType));
216 } else if(type == 2) {
217 throw new UnsupportedOperationException();
222 // for(Identity id : ids) LOGGER.warn("id: " + id);
225 // duration = System.nanoTime() - start;
226 // LOGGER.warn("ids in " + 1e-9*duration + "s.");
227 // start = System.nanoTime();
229 int stmLength = safeInt();
230 // LOGGER.warn("statements: " + stmLength + " (" + byteIndex + ")");
232 int[] statements = new int[stmLength];
234 for(int stmIndex=0;stmIndex<stmLength;) {
236 statements[stmIndex++] = safeInt();
239 int avail = (SIZE-byteIndex) >> 2;
240 int allowed = Math.min(stmLength-stmIndex, avail);
241 for(int index = byteIndex, i=0;i<allowed;i++) {
242 statements[stmIndex++] = ((bytes[index++]&0xff)<<24) | ((bytes[index++]&0xff)<<16) | ((bytes[index++]&0xff)<<8) | ((bytes[index++]&0xff));
244 byteIndex += allowed<<2;
248 // duration = System.nanoTime() - start;
249 // LOGGER.warn("stms in " + 1e-9*duration + "s.");
251 // start = System.nanoTime();
253 int valueLength = safeInt();
254 // LOGGER.warn("values: " + valueLength + " (" + byteIndex + ")");
256 Value[] values = new Value[valueLength];
258 Serializer variantSerializer = Bindings.getSerializerUnchecked(Bindings.VARIANT);
260 idcontext = new ArrayList<Object>();
261 dis = new DataInputStream(in);
263 for(int i=0;i<valueLength;i++) {
264 int resource = safeInt();
265 Variant value = (Variant)variantSerializer
266 .deserialize((DataInput)dis, idcontext);
267 values[i] = new Value(resource, value);
269 //LOGGER.warn("read variant[" + resource + "]: " + value.toString().substring(0, Math.min(100, value.toString().length())));
274 // duration = System.nanoTime() - start;
275 // LOGGER.warn("values in " + 1e-9*duration + "s.");
277 return new TransferableGraph1(resourceCount, ids, statements, values, extensions.map);
281 public static void main(String[] args) {
285 File file = new File("c:/users/antti villberg/desktop/test.apros");
286 TransferableGraphFileReader reader = new TransferableGraphFileReader(file, SIZE);
287 reader = new TransferableGraphFileReader(file);
288 long s = System.nanoTime();
290 long d = System.nanoTime() - s;
291 LOGGER.warn("Duration=" + 1e-9*d + "s.");
294 } catch (Throwable t) {