]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/LZ4.java
Fail safe import fixes made by Antti
[simantics/platform.git] / bundles / org.simantics.db.procore / src / org / simantics / db / procore / cluster / LZ4.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 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  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.db.procore.cluster;
13
14 import java.nio.ByteBuffer;
15 import java.nio.ByteOrder;
16
17 import org.simantics.compressions.Compressions;
18 import org.simantics.db.exception.InternalException;
19
20 public class LZ4 {
21     static private final int InLength = 1<<20;
22     
23     public static class DecompressStruct {
24         public long[] longs;
25         public int[] ints;
26         public byte[] bytes;
27     }
28     static class SourceData {
29         SourceData(byte[] data) {
30             this.data = data;
31             this.offset = 0;
32         }
33         int left() {
34             return data.length - offset;
35         }
36         int readInt() {
37             int inLength = 4; // sizeof(int)
38             assert(left() >= inLength); // must have data for input
39             ByteBuffer buffer = ByteBuffer.wrap(data, offset, inLength);
40             buffer.order(ByteOrder.LITTLE_ENDIAN); // argh!
41             int t = buffer.getInt();
42             offset += inLength;
43             return t;
44         }
45         void readBytes(byte[] bytes, int aOffset, int inLength) {
46             assert(left() >= inLength); // must have data for input
47             System.arraycopy(data, offset, bytes, aOffset, inLength);
48             offset += inLength;
49         }
50         byte[] data;
51         int offset;
52     }
53     public static DecompressStruct decompress(byte[] data) throws InternalException {
54         assert(data.length > 12); // 3*(table size)
55         SourceData sourceData = new SourceData(data);
56         DecompressStruct struct = new DecompressStruct();
57         int longSize = sourceData.readInt();
58         int intSize = sourceData.readInt();
59         int byteSize = sourceData.readInt();
60         struct.longs = new long[longSize]; 
61         try {
62             decompress(sourceData, struct.longs);
63             struct.ints = new int[intSize]; 
64             decompress(sourceData, struct.ints);
65             struct.bytes = new byte[byteSize];
66             decompress(sourceData, struct.bytes);
67         } catch (CompressionException e) {
68             throw new InternalException("Failed to decompress.", e);
69         }
70         return struct;
71     }
72     private static void decompress(SourceData sourceData, long[] longs) throws CompressionException {
73         int length = longs.length * 8;
74         ByteBuffer bytes = ByteBuffer.allocate(length);
75         int size = decompressRaw(sourceData, bytes.array());
76         assert(size == length);
77         bytes.order(ByteOrder.LITTLE_ENDIAN); // argh
78         for (int i=0; i<longs.length; ++i)
79             longs[i] = bytes.getLong();
80     }
81     private static void decompress(SourceData sourceData, int[] ints) throws CompressionException {
82         int length = ints.length * 4;
83         ByteBuffer bytes = ByteBuffer.allocate(length);
84         int size = decompressRaw(sourceData, bytes.array());
85         assert(size == length);
86         bytes.order(ByteOrder.LITTLE_ENDIAN); // argh
87         for (int i=0; i<ints.length; ++i)
88             ints[i] = bytes.getInt();
89     }
90     private static void decompress(SourceData sourceData, byte[] bytes) throws CompressionException {
91         int size = decompressRaw(sourceData, bytes);
92         assert(size == bytes.length);
93     }
94     private static int decompressRaw(SourceData sourceData, byte[] bytes) throws CompressionException {
95         int aDstSize = bytes.length;
96         if (aDstSize < 1)
97             return aDstSize;
98         int dstOffset = 0;
99         for (int dstSize = 0;;) {
100             int dataLength = sourceData.readInt(); 
101             assert(dataLength <= InLength); // data is written in blocks
102             if (0 == dataLength) // EOF
103                 return dstSize;
104             dstSize += dataLength;
105             int inLength = sourceData.readInt();
106
107             assert(aDstSize >= dstSize); // must have space for data
108             assert(sourceData.left() >= inLength); // must have data for input
109             assert(inLength > 0); // no data no block
110             assert(inLength <= InLength); // input size is block size or less
111             assert(inLength <= dataLength); // input size is never bigger than data size
112
113             if (inLength < dataLength) {// block was actually compressed
114                 decompress(sourceData.data, sourceData.offset, inLength, bytes, dstOffset, dataLength);
115                 sourceData.offset += inLength;
116                 dstOffset += dataLength;
117             } else {
118                 sourceData.readBytes(bytes, dstOffset, inLength);
119                 dstOffset += inLength;
120             }
121         }
122     }
123     private static void decompress(byte[] in, int inOffset, int inLength, byte[] out, int outOffset, int outLength) throws CompressionException {
124         ByteBuffer inBuffer = ByteBuffer.allocateDirect(inLength);
125         inBuffer.put(in, inOffset, inLength);
126         inBuffer.flip();
127         ByteBuffer outBuffer = ByteBuffer.allocateDirect(outLength);
128         int inflateSize = Compressions.get(Compressions.LZ4).decompressBuffer(inBuffer, 0, inLength, outBuffer, 0, outLength);
129 //        int inflateSize = org.simantics.fastlz.FastLZ.decompressBuffer(inBuffer, 0, inLength, outBuffer, 0, outLength);
130         if (inflateSize != outLength)
131             throw new RuntimeException("Decompression error.");
132         //outBuffer.flip();
133         outBuffer.get(out, outOffset, outLength);
134     }
135 }