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