]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.databoard/src/org/simantics/databoard/util/binary/DeferredBinaryFile.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / util / binary / DeferredBinaryFile.java
1 /*******************************************************************************\r
2  * Copyright (c) 2016 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     Semantum Oy - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.databoard.util.binary;
13
14 import java.io.File;\r
15 import java.io.IOException;\r
16 import java.nio.ByteBuffer;\r
17 \r
18 /**\r
19  * This class is a custom write-only wrapper for {@link BinaryFile} and\r
20  * {@link BinaryMemory} that implements a {@link RandomAccessBinary} which is\r
21  * contained fully in memory until its size reaches a user-specified threshold.\r
22  * When that size threshold is exceeded, the {@link BinaryMemory} contents are\r
23  * flushed into a BinaryFile and from there on this implementation will continue\r
24  * to write to the BinaryFile.\r
25  * <p>\r
26  * Since it is based {@link BinaryFile} and {@link BinaryMemory}, this\r
27  * implementation is also buffered and <em>not</em> thread-safe.\r
28  * <p>\r
29  * The {@link SeekableBinaryReadable} part of the {@link RandomAccessBinary}\r
30  * interface is not implemented and will throw\r
31  * {@link UnsupportedOperationException}.\r
32  *\r
33  * @author Tuukka Lehtonen\r
34  * @since 1.22.1 & 1.24.0\r
35  * @see BinaryFile\r
36  * @see BinaryMemory\r
37  */
38 public class DeferredBinaryFile implements RandomAccessBinary {
39 \r
40     File file;\r
41     int threshold;\r
42     int fileBufferSize;\r
43 \r
44     BinaryMemory memory;\r
45     RandomAccessBinary backend;
46
47     public DeferredBinaryFile(File file, int threshold, int fileBufferSize) throws IOException {\r
48         this.memory = new BinaryMemory(threshold+10000);\r
49         this.backend = memory;\r
50         this.threshold = threshold;\r
51         this.file = file;\r
52         this.fileBufferSize = fileBufferSize;\r
53     }\r
54 \r
55     /**
56      * Closes the object. Note, this will close the input random access file.\r
57      * This method may be called several times.
58      *  
59      * @throws IOException
60      */
61     @Override\r
62     public synchronized void close() throws IOException {\r
63         if (backend == null)\r
64             return;\r
65         backend.close();
66         backend = null;
67     }
68 \r
69     @Override\r
70     public synchronized boolean isOpen() {\r
71         return backend != null;\r
72     }\r
73
74     @Override
75     public byte readByte() throws IOException {
76         throw new UnsupportedOperationException();\r
77     }\r
78 \r
79     @Override\r
80     public char readChar() throws IOException {\r
81         throw new UnsupportedOperationException();\r
82     }\r
83 \r
84     @Override\r
85     public int readUnsignedByte() throws IOException {\r
86         throw new UnsupportedOperationException();\r
87     }
88 \r
89     @Override\r
90     public boolean readBoolean() throws IOException {\r
91         throw new UnsupportedOperationException();\r
92     }\r
93
94     @Override
95     public void readFully(byte[] dst, int offset, int length) throws IOException {
96         throw new UnsupportedOperationException();\r
97     }
98
99     @Override
100     public void readFully(byte[] dst) throws IOException {
101         throw new UnsupportedOperationException();\r
102     }
103
104     @Override
105     public void readFully(ByteBuffer buf) throws IOException {
106         throw new UnsupportedOperationException();\r
107     }
108
109     @Override
110     public void readFully(ByteBuffer buf, int length) throws IOException {
111         throw new UnsupportedOperationException();\r
112     }
113
114     @Override
115     public double readDouble() throws IOException {
116         throw new UnsupportedOperationException();\r
117     }
118
119     @Override
120     public float readFloat() throws IOException {
121         throw new UnsupportedOperationException();\r
122     }
123
124     @Override
125     public int readInt() throws IOException {
126         throw new UnsupportedOperationException();\r
127     }
128
129     @Override
130     public long readLong() throws IOException {
131         throw new UnsupportedOperationException();\r
132     }
133
134     @Override
135     public short readShort() throws IOException {
136         throw new UnsupportedOperationException();\r
137     }\r
138 \r
139     @Override\r
140     public int readUnsignedShort() throws IOException {\r
141         throw new UnsupportedOperationException();\r
142     }
143 \r
144     @Override\r
145     public String readUTF() throws IOException {\r
146         throw new UnsupportedOperationException();\r
147     }\r
148 \r
149     public final String readLine() throws IOException {\r
150         throw new UnsupportedOperationException();\r
151     }\r
152 \r
153     @Override
154     public long position() throws IOException {
155         return backend.position();\r
156     }
157
158     @Override\r
159     public void position(long newPosition) throws IOException {
160         backend.position(newPosition);\r
161     }
162
163     /**
164      * Flushes internal buffer
165      */
166     @Override\r
167     public void flush() throws IOException {
168         backend.flush();\r
169     }
170
171     /**
172      * Clears read&write buffer. The file can be modified elsewhere after this.
173      * 
174      * @throws IOException 
175      */
176     @Override\r
177     public void reset() throws IOException {
178         backend.reset();\r
179     }
180 \r
181     @Override\r
182     public long skipBytes(long bytes) throws IOException {\r
183         return backend.skipBytes(bytes);\r
184     }\r
185
186     @Override\r
187     public int skipBytes(int bytes) throws IOException {\r
188         return backend.skipBytes(bytes);\r
189     }\r
190 \r
191 \r
192     // WRITE
193
194     @Override
195     public void write(int b) throws IOException {
196         backend.write(b);\r
197         if (memory != null)\r
198             threshold();\r
199     }\r
200 \r
201     @Override\r
202     public void writeByte(int b) throws IOException {\r
203         backend.writeByte(b);\r
204         if (memory != null)\r
205             threshold();\r
206     }
207 \r
208     @Override\r
209     public void writeBoolean(boolean v) throws IOException {\r
210         backend.writeBoolean(v);\r
211         if (memory != null)\r
212             threshold();\r
213     }\r
214
215     @Override
216     public void writeFully(ByteBuffer src) throws IOException {
217         backend.writeFully(src);\r
218         if (memory != null)\r
219             threshold();\r
220     }
221
222     @Override
223     public void writeFully(ByteBuffer src, int length) throws IOException {
224         backend.writeFully(src, length);\r
225         if (memory != null)\r
226             threshold();\r
227     }
228
229     @Override
230     public void write(byte[] src, int offset, int length) throws IOException {
231         backend.write(src, offset, length);\r
232     }
233
234     @Override
235     public void write(byte[] src) throws IOException {
236         backend.write(src);\r
237         if (memory != null)\r
238             threshold();\r
239     }
240
241     @Override
242     public void writeDouble(double value) throws IOException {
243         backend.writeDouble(value);\r
244         if (memory != null)\r
245             threshold();\r
246     }
247
248     @Override
249     public void writeFloat(float value) throws IOException {
250         backend.writeFloat(value);\r
251         if (memory != null)\r
252             threshold();\r
253     }
254
255     @Override
256     public void writeInt(int value) throws IOException {
257         backend.writeInt(value);\r
258         if (memory != null)\r
259             threshold();\r
260     }
261
262     @Override
263     public void writeLong(long value) throws IOException {
264         backend.writeLong(value);\r
265         if (memory != null)\r
266             threshold();\r
267     }
268
269     @Override
270     public void writeShort(int value) throws IOException {
271         backend.writeShort(value);\r
272         if (memory != null)\r
273             threshold();\r
274     }\r
275 \r
276     @Override\r
277     public void writeChar(int value) throws IOException {\r
278         backend.writeChar(value);\r
279         if (memory != null)\r
280             threshold();\r
281     }\r
282 \r
283     @Override\r
284     public void writeBytes(String s) throws IOException {\r
285         backend.writeBytes(s);\r
286         if (memory != null)\r
287             threshold();\r
288     }\r
289 \r
290     @Override\r
291     public void writeChars(String s) throws IOException {\r
292         backend.writeChars(s);\r
293         if (memory != null)\r
294             threshold();\r
295     }
296 \r
297     @Override\r
298     public void writeUTF(String s) throws IOException {\r
299         backend.writeUTF(s);\r
300         if (memory != null)\r
301             threshold();\r
302     }\r
303
304     @Override
305     public void insertBytes(long bytes, ByteSide side) throws IOException {
306         throw new UnsupportedOperationException();\r
307     }
308
309     @Override
310     public void removeBytes(long bytes, ByteSide side) throws IOException {
311         throw new UnsupportedOperationException();\r
312     }
313
314     @Override
315     public long length() throws IOException {
316         return backend.length();
317     }
318
319     @Override
320     public void setLength(long newLength) throws IOException {\r
321         throw new UnsupportedOperationException();
322     }
323
324     @Override
325     public String toString() {
326         try {
327             return "DeferredBinaryFile(file="+file.getName()+", size="+length()+")";
328         } catch (IOException e) {
329             return "DeferredBinaryFile()";
330         }
331     }\r
332 \r
333     private void threshold() throws IOException {\r
334         if (backend.position() >= threshold) {\r
335             backend = new BinaryFile(file, fileBufferSize);\r
336             long length = memory.position();\r
337             memory.position(0);\r
338             memory.toByteBuffer().position(0);\r
339             backend.writeFully(memory.toByteBuffer(), (int) length);\r
340             memory = null;\r
341         }\r
342     }\r
343 \r
344     public boolean isInMemory() {\r
345         return memory != null;\r
346     }\r
347 \r
348     public RandomAccessBinary getMemory() {\r
349         return memory;\r
350     }\r
351 \r
352     public RandomAccessBinary getBackend() {\r
353         return backend;\r
354     }\r
355 \r
356 }