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