]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.graph/src/org/simantics/graph/representation/TransferableGraphFileReader.java
Fixing PrettyPrintTG to not concatenate strings in logging
[simantics/platform.git] / bundles / org.simantics.graph / src / org / simantics / graph / representation / TransferableGraphFileReader.java
1 package org.simantics.graph.representation;
2
3 import java.io.DataInput;
4 import java.io.DataInputStream;
5 import java.io.File;
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;
12
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
22
23 final public class TransferableGraphFileReader extends ByteFileReader {
24
25         InputStream in = new InputStream() {
26
27         @Override
28         public int read() throws IOException {
29             return getByte();
30         }
31         
32         @Override
33         public int read(byte[] b) throws IOException {
34             // FIXME not correctly implemented                
35             System.arraycopy(safeBytes(b.length), 0, b, 0, b.length);
36             return b.length;
37         }
38         
39         @Override
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);
43             return len;
44         }
45             
46         };
47         
48         
49         final static class InputChannel implements ReadableByteChannel {
50
51                 final private InputStream stream;
52                 
53                 public InputChannel(InputStream stream) {
54                         this.stream = stream;
55                 }
56                 
57                 @Override
58                 public boolean isOpen() {
59                         return true;
60                 }
61
62                 @Override
63                 public void close() throws IOException {
64                 }
65
66                 @Override
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 + ")");
72                         return i;
73                 }
74                 
75         }
76         
77         private static boolean init = true;
78         
79         final private static int SIZE = 1<<18;
80         final private static int HEADER = headerSize();
81         final private int header;
82         
83         public TransferableGraphFileReader(File file) throws IOException {
84                 super(file, SIZE);
85                 if(init) {
86                         init=false;
87                         TransferableGraphFileReader r = new TransferableGraphFileReader(file, 0);
88                         for(int i=0;i<40000;i++) r.readTG();
89                 }
90                 this.header = HEADER;
91         }
92         
93         public TransferableGraphFileReader(InputStream stream) throws IOException {
94                 super(null, new InputChannel(stream), SIZE);
95                 if(init) {
96                         init=false;
97                         TransferableGraphFileReader r = new TransferableGraphFileReader(stream, 0);
98                         for(int i=0;i<40000;i++) r.readTG();
99                 }
100                 this.header = 0;
101         }
102
103         public TransferableGraphFileReader(ReadableByteChannel channel) throws IOException {
104                 super(null, channel, SIZE);
105                 if(init) {
106                         init=false;
107                         TransferableGraphFileReader r = new TransferableGraphFileReader(channel, 0);
108                         for(int i=0;i<40000;i++) r.readTG();
109                 }
110                 this.header = 0;
111         }
112
113         public TransferableGraphFileReader(ReadableByteChannel channel, int size) throws IOException {
114                 super(null, channel, SIZE);
115                 this.header = 0;
116         }
117
118         public TransferableGraphFileReader(InputStream stream, int size) throws IOException {
119                 super(null, new InputChannel(stream), size);
120                 this.header = 0;
121         }
122
123         public TransferableGraphFileReader(File file, int size) throws IOException {
124                 super(file, size);
125                 this.header = HEADER;
126         }
127
128         private static int headerSize() {
129                 try {
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);
137                 }               
138         }
139         
140         public TransferableGraph1 readTG() throws IOException {
141
142                 if(getSize() == 0) return null;
143                 
144 //              long start = System.nanoTime();
145
146                 final byte[] bytes = getBytes();
147                 
148 //              byteIndex = header;
149
150                 DataInputStream dis = new DataInputStream(in);
151
152                 // Header
153                 DataContainers.readHeader(dis);
154                 
155                 // Content variant data type
156                 Bindings.getSerializerUnchecked(Datatype.class).deserialize((DataInput)dis);
157
158                 int resourceCount = safeInt();
159                 
160                 List<Object> idcontext = new ArrayList<Object>(); 
161                 dis = new DataInputStream(in);
162                 Extensions extensions = (Extensions)Bindings.getSerializerUnchecked(Extensions.class).deserialize((DataInput)dis, idcontext);
163                 
164                 int identities = safeInt();
165                 Identity[] ids = new Identity[identities];
166
167 //              System.err.println("rc: " + resourceCount);
168 //              System.err.println("ids: " + identities);
169                 
170 //              long duration = System.nanoTime() - start;
171 //              System.err.println("start in " + 1e-9*duration + "s.");
172 //              start = System.nanoTime();
173                 
174                 for(int i=0;i<identities;i++) {
175                         int rid = safeInt();
176                         byte type = bytes[byteIndex++];
177                         // External
178                         if(type == 1) {
179                                 
180                                 int parent = safeInt();
181                                 int nameLen = getDynamicUInt32();
182                                 
183                                 if(byteIndex+nameLen < SIZE) {
184                                         ids[i] = new Identity(rid, new External(parent, utf(bytes, byteIndex, byteIndex + nameLen)));
185                                         byteIndex += nameLen;
186                                 } else {
187                                         ids[i] = new Identity(rid, new External(parent, utf(safeBytes(nameLen), 0, nameLen)));
188                                 }
189                                 
190                         } 
191                         // Internal
192                         else if(type == 3) {
193                                 
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;
199                                 } else {
200                                         ids[i] = new Identity(rid, new Internal(parent, utf(safeBytes(nameLen), 0, nameLen)));
201                                 }
202                                 
203                         }
204                         // Root
205                         else if(type == 0) {
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));
211
212                         } else if(type == 2) {
213                                 throw new UnsupportedOperationException();
214                         }
215
216                 }
217
218 //              for(Identity id : ids) System.err.println("id: " + id);
219
220                 
221 //              duration = System.nanoTime() - start;
222 //              System.err.println("ids in " + 1e-9*duration + "s.");
223 //              start = System.nanoTime();
224
225                 int stmLength = safeInt();
226 //              System.err.println("statements: " + stmLength + " (" + byteIndex + ")");
227                 
228                 int[] statements = new int[stmLength];
229
230                 for(int stmIndex=0;stmIndex<stmLength;) {
231
232                         statements[stmIndex++] = safeInt();
233                         
234                         // Cached bytes 
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));                              
239                         }
240                         byteIndex += allowed<<2;
241                         
242                 }
243
244 //              duration = System.nanoTime() - start;
245 //              System.err.println("stms in " + 1e-9*duration + "s.");
246 //              
247 //              start = System.nanoTime();
248
249                 int valueLength = safeInt();
250 //              System.err.println("values: " + valueLength + " (" + byteIndex + ")");
251
252                 Value[] values = new Value[valueLength]; 
253
254                 Serializer variantSerializer = Bindings.getSerializerUnchecked(Bindings.VARIANT);
255                 
256                 idcontext = new ArrayList<Object>(); 
257                 dis = new DataInputStream(in);
258                 
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);
264                         
265                         //System.err.println("read variant[" + resource + "]: " + value.toString().substring(0, Math.min(100, value.toString().length())));
266                         
267                 }
268
269                 
270 //              duration = System.nanoTime() - start;
271 //              System.err.println("values in " + 1e-9*duration + "s.");
272                 
273                 return new TransferableGraph1(resourceCount, ids, statements, values, extensions.map);
274
275         }
276         
277         public static void main(String[] args) {
278
279                 try {
280                         
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();
285                         reader.readTG();
286                         long d = System.nanoTime() - s;
287                         System.err.println("Duration=" + 1e-9*d + "s.");
288                         
289                         
290                 } catch (Throwable t) {
291                         t.printStackTrace();
292                 }
293                 
294         }
295
296 }