1 /*******************************************************************************
\r
2 t * Copyright (c) 2007, 2010 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
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.fastlz;
14 import static org.junit.Assert.fail;
\r
16 import java.io.BufferedInputStream;
\r
17 import java.io.BufferedOutputStream;
\r
18 import java.io.File;
\r
19 import java.io.FileInputStream;
\r
20 import java.io.FileOutputStream;
\r
21 import java.io.IOException;
\r
22 import java.io.InputStream;
\r
23 import java.io.OutputStream;
\r
24 import java.util.Arrays;
\r
26 import junit.framework.Assert;
\r
28 import org.junit.BeforeClass;
\r
29 import org.junit.Test;
\r
32 * @author Tuukka Lehtonen
\r
34 @SuppressWarnings("deprecation")
\r
35 public class FastLZBasicTests {
\r
37 static File testData1;
\r
38 static File testData2;
\r
39 static File testDataPrime;
\r
42 public static void initialize() throws IOException {
\r
43 FastLZ.initialize(null);
\r
45 testData1 = new File("uncompressed.data");
\r
46 writeTestData(testData1, 10000000);
\r
47 testData2 = new File("uncompressed-small.data");
\r
48 writeTestData(testData2, 100000);
\r
49 testDataPrime = new File("uncompressed-prime.data");
\r
50 writeTestData(testDataPrime, 1000);
\r
52 System.out.println("test data directory: " + testData1.getAbsolutePath());
\r
54 // File javaFlz = new File("compressed-prime.data.native.flz");
\r
55 // for (int i = 0; i < 100; ++i) {
\r
56 // compressFlzJava(testDataPrime, javaFlz);
\r
61 public void validateCompress() throws IOException {
\r
62 validateCompress(testData1);
\r
65 private void validateCompress(File testData) throws IOException {
\r
66 System.out.println("==== validateCompress(" + testData.getName() + ") ====");
\r
68 File nativeFlz = new File("compressed.data.native.flz");
\r
69 long nativeCompressedSize = compressFlzNative(testData, nativeFlz);
\r
70 System.out.println("native compressed size: " + nativeCompressedSize);
\r
72 // Need to prime JVM JIT by performing multiple passes
\r
73 File javaFlz = new File("compressed.data.java.flz");
\r
74 long javaCompressedSize = compressFlzJava(testData, javaFlz);
\r
75 System.out.println("java compressed size: " + javaCompressedSize);
\r
77 Assert.assertEquals(nativeCompressedSize, javaCompressedSize);
\r
79 System.out.println("Comparing compressed outputs...");
\r
80 compareFiles(nativeFlz, javaFlz);
\r
81 System.out.println("Compressed outputs match.");
\r
83 File decompressedNativeFlz = new File("decompressed.data.native.flz");
\r
84 File decompressedJavaFlz = new File("decompressed.data.java.flz");
\r
85 decompressFlzNative(nativeFlz, decompressedNativeFlz);
\r
86 decompressFlzNative(javaFlz, decompressedJavaFlz);
\r
87 compareFiles(decompressedJavaFlz, decompressedNativeFlz);
\r
88 compareFiles(decompressedNativeFlz, testData);
\r
92 // public void validateCompressSmall() throws IOException {
\r
93 // File nativeFlz = new File("compressed-small.data.native.flz");
\r
94 // long nativeCompressedSize = compressFlzNative(testData2, nativeFlz);
\r
95 // System.out.println("native compressed size: " + nativeCompressedSize);
\r
97 // // Need to prime JVM JIT by performing multiple passes
\r
98 // File javaFlz = new File("compressed-small.data.java.flz");
\r
99 // long javaCompressedSize = compressFlzJava(testData2, javaFlz);
\r
100 // System.out.println("java compressed size: " + javaCompressedSize);
\r
102 // Assert.assertEquals(nativeCompressedSize, javaCompressedSize);
\r
104 // System.out.println("Comparing compressed outputs...");
\r
105 // compareFiles(nativeFlz, javaFlz);
\r
106 // System.out.println("Compressed outputs match.");
\r
110 // public void testNativeCompressPerformance() throws IOException {
\r
111 // File javaFlz = new File("compressed.data.native.flz");
\r
112 // for (int i = 0; i < 5; ++i) {
\r
113 // compressFlzNative(testData1, javaFlz);
\r
118 // public void testJavaCompressPerformance() throws IOException {
\r
119 // // Need to prime JVM JIT by performing multiple passes
\r
120 // File javaFlz = new File("compressed.data.java.flz");
\r
121 // for (int i = 0; i < 5; ++i) {
\r
122 // compressFlzJava(testData1, javaFlz);
\r
127 // public void testCompressNative() throws IOException {
\r
128 // File flz = new File("compressed.data.native.flz");
\r
129 // for (int i = 0; i < 5; ++i) {
\r
130 // long compressedSize = compressFlzNative(testData1, flz);
\r
131 // System.out.println("native compressed size: " + compressedSize);
\r
136 // public void testCompressionJava() throws IOException {
\r
137 // // Need to prime JVM JIT by performing multiple passes
\r
138 // File flz = new File("compressed.data.java.flz");
\r
139 // for (int i = 0; i < 5; ++i) {
\r
140 // long compressedSize = compressFlzJava(testData1, flz);
\r
141 // System.out.println("java compressed size: " + compressedSize);
\r
145 @SuppressWarnings("unused")
\r
147 public void testDecompress() throws IOException {
\r
148 File nativeFlz = new File("compressed.data.native.flz");
\r
149 long nativeCompressedSize = compressFlzNative(testData1, nativeFlz);
\r
150 System.out.println("native compressed size: " + nativeCompressedSize);
\r
152 // Need to prime JVM JIT by performing multiple passes
\r
153 File javaFlz = new File("compressed.data.java.flz");
\r
154 long javaCompressedSize = compressFlzJava(testData1, javaFlz);
\r
155 System.out.println("java compressed size: " + javaCompressedSize);
\r
157 Assert.assertEquals(nativeCompressedSize, javaCompressedSize);
\r
159 System.out.println("Comparing compressed outputs...");
\r
160 compareFiles(nativeFlz, javaFlz);
\r
161 System.out.println("Compressed outputs match.");
\r
163 File java1 = new File("java-compressed.data.decompressed-with-native");
\r
164 long nativeDecompressedSize = decompressFlzNative(javaFlz, java1);
\r
165 System.out.println("Comparing native-decompressed output...");
\r
166 compareFiles(testData1, java1);
\r
167 System.out.println("Native-decompressed output matches original.");
\r
169 File java2 = new File("java-compressed.data.decompressed-with-java");
\r
170 long javaDecompressedSize = decompressFlzJava(javaFlz, java2);
\r
171 System.out.println("Comparing java-decompressed output...");
\r
172 compareFiles(testData1, java2);
\r
173 System.out.println("Java-decompressed output matches original.");
\r
175 for (int i = 0; i < 5; ++i)
\r
176 decompressFlz(javaFlz, FastLZ.read(javaFlz), java1, NullOutputStream.INSTANCE);
\r
177 for (int i = 0; i < 5; ++i)
\r
178 decompressFlz(javaFlz, FastLZJava.read(javaFlz), java2, NullOutputStream.INSTANCE);
\r
182 public void testDecompressCluster() {
183 fail("Not yet implemented");
186 static void compareFiles(File file1, File file2) throws IOException {
\r
187 InputStream in1 = new BufferedInputStream(new FileInputStream(file1));
\r
188 InputStream in2 = new BufferedInputStream(new FileInputStream(file2));
\r
192 int b1 = in1.read();
\r
193 int b2 = in2.read();
\r
194 if (b1 == -1 && b2 == -1)
\r
197 fail("EOF reached in file1 " + file1.getName() + " but not in file2 " + file2.getName());
\r
199 fail("EOF reached in file1 " + file1.getName() + " but not in file2 " + file2.getName());
\r
201 fail("bytes at offset " + offset + " do not match: " + b1 + " vs. " + b2);
\r
210 public static void writeTestData(File file, int rows) throws IOException {
\r
214 System.out.println("writing test data...");
\r
215 OutputStream stream = new FileOutputStream(file);
\r
216 for (int i = 0; i < rows; ++i)
\r
217 stream.write((Integer.toString(i) + "\n").getBytes());
\r
219 System.out.println("wrote " + file.length() + " bytes of test data.");
\r
225 * @return compressed size in bytes
\r
226 * @throws IOException
\r
228 static long compressFlzJava(File source, File flz) throws IOException {
\r
229 return compressFlz(source, flz, FastLZJava.write(flz));
\r
235 * @return compressed size in bytes
\r
236 * @throws IOException
\r
238 static long compressFlzNative(File source, File flz) throws IOException {
\r
239 return compressFlz(source, flz, FastLZ.write(flz));
\r
245 * @return compressed size in bytes
\r
246 * @throws IOException
\r
248 static long compressFlz(File source, File flz, OutputStream flzOutput) throws IOException {
\r
249 System.out.println("compressFlz(" + source + ", " + flz + ")");
\r
250 InputStream input = new BufferedInputStream(new FileInputStream(source));
\r
251 copy(input, flzOutput);
\r
254 long compressed = flz.length();
\r
255 System.out.println("Wrote " + compressed + " compressed bytes");
\r
262 * @return compressed size in bytes
\r
263 * @throws IOException
\r
265 static long decompressFlzJava(File flz, File dest) throws IOException {
\r
266 return decompressFlz(flz, FastLZJava.read(flz), dest);
\r
272 * @return compressed size in bytes
\r
273 * @throws IOException
\r
275 static long decompressFlzNative(File flz, File dest) throws IOException {
\r
276 return decompressFlz(flz, FastLZ.read(flz), dest);
\r
282 * @return compressed size in bytes
\r
283 * @throws IOException
\r
285 static long decompressFlz(File source, InputStream flzInput, File dest) throws IOException {
\r
286 System.out.println("decompressFlz(" + source + ", " + dest + ")");
\r
287 OutputStream output = new BufferedOutputStream(new FileOutputStream(dest));
\r
288 copy(flzInput, output);
\r
291 long decompressed = dest.length();
\r
292 System.out.println("Wrote " + decompressed + " decompressed bytes");
\r
293 return decompressed;
\r
299 * @return compressed size in bytes
\r
300 * @throws IOException
\r
302 static long decompressFlz(File source, InputStream flzInput, File dest, OutputStream destStream) throws IOException {
\r
303 System.out.println("decompressFlz(" + source + ", " + dest + ")");
\r
304 copy(flzInput, destStream);
\r
306 destStream.close();
\r
307 long decompressed = dest.length();
\r
308 System.out.println("Wrote " + decompressed + " decompressed bytes");
\r
309 return decompressed;
\r
313 * Copy the content of the input stream into the output stream, using a temporary
\r
314 * byte array buffer whose size is defined by {@link #IO_BUFFER_SIZE}.
\r
316 * @param in The input stream to copy from.
\r
317 * @param out The output stream to copy to.
\r
319 * @throws IOException If any error occurs during the copy.
\r
321 private static final int IO_BUFFER_SIZE = 128 * 1024;
\r
323 public static long copy(InputStream in, OutputStream out) throws IOException {
\r
324 byte[] b = new byte[IO_BUFFER_SIZE];
\r
327 long start = System.nanoTime();
\r
333 //System.out.println("read " + read + " bytes, " + total + " bytes in total");
\r
334 out.write(b, 0, read);
\r
337 long end = System.nanoTime();
\r
338 double totalmb = total/(1024.0*1024.0);
\r
339 double time = (end-start)*1e-9;
\r
340 double rate = totalmb / time;
\r
341 System.out.format("Transferred %d bytes (%.3f Mbytes) in %f seconds (%.3f MB/s)\n", total, totalmb, time, rate);
\r
346 @SuppressWarnings("unused")
\r
347 private boolean checksumsEqual(File f1, File f2) throws IOException {
\r
348 byte[] s1 = ChecksumUtil.computeSum(f1);
\r
349 byte[] s2 = ChecksumUtil.computeSum(f2);
\r
350 return Arrays.equals(s1, s2);
\r