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